зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c.
This commit is contained in:
Коммит
7f9a1195fb
|
@ -415,6 +415,10 @@ SettingsListener.observe('privacy.donottrackheader.enabled', false, function(val
|
|||
Services.prefs.setBoolPref('privacy.donottrackheader.enabled', value);
|
||||
});
|
||||
|
||||
SettingsListener.observe('privacy.donottrackheader.value', 1, function(value) {
|
||||
Services.prefs.setIntPref('privacy.donottrackheader.value', value);
|
||||
});
|
||||
|
||||
// =================== Crash Reporting ====================
|
||||
SettingsListener.observe('app.reportCrashes', 'ask', function(value) {
|
||||
if (value == 'always') {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
.text-link {
|
||||
color: #fff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.text-link:-moz-focusring {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
.text-link {
|
||||
color: #fff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.text-link:-moz-focusring {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
.text-link {
|
||||
color: #fff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#rightBox {
|
||||
|
|
|
@ -44,6 +44,11 @@ function test() {
|
|||
let tab;
|
||||
Task.spawn(function() {
|
||||
try {
|
||||
let SESSION_STORAGE_KEY = "SESSION_STORAGE_KEY " + Math.random();
|
||||
let SESSION_STORAGE_VALUE = "SESSION_STORAGE_VALUE " + Math.random();
|
||||
let LOCAL_STORAGE_KEY = "LOCAL_STORAGE_KEY " + Math.random();
|
||||
let LOCAL_STORAGE_VALUE = "LOCAL_STORAGE_VALUE " + Math.random();
|
||||
|
||||
tab = gBrowser.addTab("http://example.com");
|
||||
// about:home supports sessionStorage and localStorage
|
||||
|
||||
|
@ -57,25 +62,27 @@ function test() {
|
|||
ss.getBrowserState();
|
||||
|
||||
info("Change sessionStorage, ensure that state is saved");
|
||||
win.sessionStorage["SESSION_STORAGE_KEY"] = "SESSION_STORAGE_VALUE";
|
||||
let storageChanged = yield waitForStorageChange(tab);
|
||||
let storageChangedPromise = waitForStorageChange(tab);
|
||||
win.sessionStorage[SESSION_STORAGE_KEY] = SESSION_STORAGE_VALUE;
|
||||
let storageChanged = yield storageChangedPromise;
|
||||
ok(storageChanged, "Changing sessionStorage triggered the right message");
|
||||
yield forceWriteState();
|
||||
|
||||
let state = ss.getBrowserState();
|
||||
ok(state.indexOf("SESSION_STORAGE_KEY") != -1, "Key appears in state");
|
||||
ok(state.indexOf("SESSION_STORAGE_VALUE") != -1, "Value appears in state");
|
||||
ok(state.indexOf(SESSION_STORAGE_KEY) != -1, "Key appears in state");
|
||||
ok(state.indexOf(SESSION_STORAGE_VALUE) != -1, "Value appears in state");
|
||||
|
||||
|
||||
info("Change localStorage, ensure that state is not saved");
|
||||
win.localStorage["LOCAL_STORAGE_KEY"] = "LOCAL_STORAGE_VALUE";
|
||||
storageChanged = yield waitForStorageChange(tab);
|
||||
storageChangedPromise = waitForStorageChange(tab);
|
||||
win.localStorage[LOCAL_STORAGE_KEY] = LOCAL_STORAGE_VALUE;
|
||||
storageChanged = yield storageChangedPromise;
|
||||
ok(!storageChanged, "Changing localStorage did not trigger a message");
|
||||
yield forceWriteState();
|
||||
|
||||
state = ss.getBrowserState();
|
||||
ok(state.indexOf("LOCAL_STORAGE_KEY") == -1, "Key does not appear in state");
|
||||
ok(state.indexOf("LOCAL_STORAGE_VALUE") == -1, "Value does not appear in state");
|
||||
ok(state.indexOf(LOCAL_STORAGE_KEY) == -1, "Key does not appear in state");
|
||||
ok(state.indexOf(LOCAL_STORAGE_VALUE) == -1, "Value does not appear in state");
|
||||
} catch (ex) {
|
||||
ok(false, ex);
|
||||
info(ex.stack);
|
||||
|
|
|
@ -552,6 +552,9 @@ MOCHITEST_FILES_C= \
|
|||
test_bug708620.html \
|
||||
file_bug708620.html \
|
||||
file_bug708620-2.html \
|
||||
test_XHR_timeout.html \
|
||||
test_XHR_timeout.js \
|
||||
file_XHR_timeout.sjs \
|
||||
test_bug717511.html \
|
||||
file_bug717511.html \
|
||||
file_bug717511.html^headers^ \
|
||||
|
@ -701,11 +704,6 @@ MOCHITEST_FILES_PARTS = $(foreach s,A B C,MOCHITEST_FILES_$(s))
|
|||
# test_bug503473.html \
|
||||
# file_bug503473-frame.sjs \
|
||||
|
||||
# Disabled for frequent failures (bug 841505, bug 842344, etc)
|
||||
# test_XHR_timeout.html \
|
||||
# test_XHR_timeout.js \
|
||||
# file_XHR_timeout.sjs \
|
||||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
browser_bug593387.js \
|
||||
browser_bug902350.js \
|
||||
|
|
|
@ -80,6 +80,7 @@ var interfaceNamesInGlobalScope =
|
|||
"Attr",
|
||||
"Audio",
|
||||
"AudioBuffer",
|
||||
{name: "AudioChannelManager", b2g: true},
|
||||
"AudioContext",
|
||||
"AudioBufferSourceNode",
|
||||
"AudioDestinationNode",
|
||||
|
@ -94,8 +95,14 @@ var interfaceNamesInGlobalScope =
|
|||
"BiquadFilterNode",
|
||||
"Blob",
|
||||
"BlobEvent",
|
||||
{name: "BluetoothAdapter", b2g: true},
|
||||
{name: "BluetoothDevice", b2g: true},
|
||||
{name: "BluetoothDeviceEvent", b2g: true},
|
||||
{name: "BluetoothManager", b2g: true},
|
||||
{name: "BluetoothStatusChangedEvent", b2g: true},
|
||||
{name: "BoxObject", xbl: true},
|
||||
{name: "BrowserFeedWriter", android: false},
|
||||
{name: "BrowserFeedWriter", desktop: true},
|
||||
{name: "CallEvent", b2g: true},
|
||||
"CameraCapabilities",
|
||||
"CameraControl",
|
||||
"CameraManager",
|
||||
|
@ -104,6 +111,7 @@ var interfaceNamesInGlobalScope =
|
|||
"CanvasRenderingContext2D",
|
||||
"CaretPosition",
|
||||
"CDATASection",
|
||||
{name: "CFStateChangeEvent", b2g: true},
|
||||
"ChannelMergerNode",
|
||||
"ChannelSplitterNode",
|
||||
"CharacterData",
|
||||
|
@ -117,7 +125,7 @@ var interfaceNamesInGlobalScope =
|
|||
"CompositionEvent",
|
||||
"Controllers",
|
||||
"ConvolverNode",
|
||||
{name: "CRMFObject", android: false},
|
||||
{name: "CRMFObject", desktop: true},
|
||||
"Crypto",
|
||||
"CSS",
|
||||
"CSS2Properties",
|
||||
|
@ -144,6 +152,7 @@ var interfaceNamesInGlobalScope =
|
|||
"CustomEvent",
|
||||
"DataChannel",
|
||||
"DataContainerEvent",
|
||||
{name: "DataErrorEvent", b2g: true},
|
||||
"DataTransfer",
|
||||
"DelayNode",
|
||||
"DesktopNotification",
|
||||
|
@ -185,13 +194,14 @@ var interfaceNamesInGlobalScope =
|
|||
"FileList",
|
||||
"FileReader",
|
||||
"FileRequest",
|
||||
{name: "FMRadio", b2g: true},
|
||||
"FocusEvent",
|
||||
"FormData",
|
||||
"GainNode",
|
||||
{name: "Gamepad", android: false},
|
||||
{name: "GamepadAxisMoveEvent", android: false},
|
||||
{name: "GamepadButtonEvent", android: false},
|
||||
{name: "GamepadEvent", android: false},
|
||||
{name: "Gamepad", desktop: true},
|
||||
{name: "GamepadAxisMoveEvent", desktop: true},
|
||||
{name: "GamepadButtonEvent", desktop: true},
|
||||
{name: "GamepadEvent", desktop: true},
|
||||
"HashChangeEvent",
|
||||
"History",
|
||||
"HTMLAnchorElement",
|
||||
|
@ -265,6 +275,7 @@ var interfaceNamesInGlobalScope =
|
|||
"HTMLUListElement",
|
||||
"HTMLUnknownElement",
|
||||
"HTMLVideoElement",
|
||||
{name: "IccCardLockErrorEvent", b2g: true},
|
||||
"IDBCursor",
|
||||
"IDBCursorWithValue",
|
||||
"IDBDatabase",
|
||||
|
@ -279,7 +290,7 @@ var interfaceNamesInGlobalScope =
|
|||
"IDBVersionChangeEvent",
|
||||
"Image",
|
||||
"ImageData",
|
||||
{name: "InstallTrigger", xbl: false},
|
||||
{name: "InstallTrigger", b2g: false, xbl: false},
|
||||
"KeyEvent",
|
||||
"KeyboardEvent",
|
||||
"LoadStatus",
|
||||
|
@ -302,18 +313,28 @@ var interfaceNamesInGlobalScope =
|
|||
"ModalContentWindow",
|
||||
"MouseEvent",
|
||||
"MouseScrollEvent",
|
||||
{name: "MozActivity", b2g: true},
|
||||
"MozApplicationEvent",
|
||||
"MozCanvasPrintState",
|
||||
{name: "MozCellBroadcast", b2g: true},
|
||||
{name: "MozCellBroadcastEvent", b2g: true},
|
||||
"MozConnection",
|
||||
"mozContact",
|
||||
"MozContactChangeEvent",
|
||||
"MozCSSKeyframeRule",
|
||||
"MozCSSKeyframesRule",
|
||||
{name: "MozEmergencyCbModeEvent", b2g: true},
|
||||
{name: "MozIccManager", b2g: true},
|
||||
{name: "MozInputContext", b2g: true},
|
||||
{name: "MozInputMethod", b2g: true},
|
||||
{name: "MozInputMethodManager", b2g: true},
|
||||
"MozMmsEvent",
|
||||
"MozMmsMessage",
|
||||
{name: "MozMobileConnection", b2g: true},
|
||||
"MozMobileMessageManager",
|
||||
"MozMobileMessageThread",
|
||||
"MozNamedAttrMap",
|
||||
{name: "MozOtaStatusEvent", b2g: true},
|
||||
"MozPowerManager",
|
||||
"mozRTCIceCandidate",
|
||||
"mozRTCPeerConnection",
|
||||
|
@ -323,7 +344,13 @@ var interfaceNamesInGlobalScope =
|
|||
"MozSmsFilter",
|
||||
"MozSmsMessage",
|
||||
"MozSmsSegmentInfo",
|
||||
{name: "MozStkCommandEvent", b2g: true},
|
||||
{name: "MozTimeManager", b2g: true},
|
||||
{name: "MozVoicemail", b2g: true},
|
||||
{name: "MozVoicemailEvent", b2g: true},
|
||||
"MozWakeLock",
|
||||
{name: "MozWifiConnectionInfoEvent", b2g: true},
|
||||
{name: "MozWifiStatusChangeEvent", b2g: true},
|
||||
"MutationEvent",
|
||||
"MutationObserver",
|
||||
"MutationRecord",
|
||||
|
@ -355,8 +382,8 @@ var interfaceNamesInGlobalScope =
|
|||
"PopupBlockedEvent",
|
||||
"ProcessingInstruction",
|
||||
"ProgressEvent",
|
||||
{name: "Promise", release: false},
|
||||
{name: "PromiseResolver", release: false},
|
||||
{name: "Promise", b2g: false, release: false},
|
||||
{name: "PromiseResolver", b2g: false, release: false},
|
||||
"PropertyNodeList",
|
||||
"Range",
|
||||
"RecordErrorEvent",
|
||||
|
@ -504,6 +531,9 @@ var interfaceNamesInGlobalScope =
|
|||
"SVGViewElement",
|
||||
"SVGZoomAndPan",
|
||||
"SVGZoomEvent",
|
||||
{name: "Telephony", b2g: true},
|
||||
{name: "TelephonyCall", b2g: true},
|
||||
{name: "TelephonyCallGroup", b2g: true},
|
||||
"Text",
|
||||
"TextDecoder",
|
||||
"TextEncoder",
|
||||
|
@ -524,6 +554,7 @@ var interfaceNamesInGlobalScope =
|
|||
"URL",
|
||||
{name: "UserDataHandler", xbl: true},
|
||||
"UserProximityEvent",
|
||||
{name: "USSDReceivedEvent", b2g: true},
|
||||
"ValidityState",
|
||||
"VideoStreamTrack",
|
||||
"WaveShaperNode",
|
||||
|
@ -572,7 +603,8 @@ function createInterfaceMap(isXBLScope) {
|
|||
var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.contains("a");
|
||||
var isAndroid = navigator.userAgent.indexOf("Android") >= 0;
|
||||
var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
|
||||
var isB2G = !isDesktop && !navigator.userAgent.contains("Android");
|
||||
var interfaceMap = {};
|
||||
for (var entry of ecmaGlobals) {
|
||||
if (typeof(entry) === "string") {
|
||||
|
@ -587,12 +619,13 @@ function createInterfaceMap(isXBLScope) {
|
|||
for (var entry of interfaceNamesInGlobalScope) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if (entry.xbl === isXBLScope ||
|
||||
entry.android === isAndroid ||
|
||||
entry.release === isRelease) {
|
||||
interfaceMap[entry.name] = true;
|
||||
} else {
|
||||
} else if (entry.xbl === !isXBLScope ||
|
||||
entry.desktop === !isDesktop ||
|
||||
entry.b2g === !isB2G ||
|
||||
entry.release === !isRelease) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
return interfaceMap;
|
||||
|
|
|
@ -93,6 +93,7 @@ MOCHITEST_FILES = \
|
|||
test_xhr_parameters.js \
|
||||
test_xhr_system.html \
|
||||
test_xhr_system.js \
|
||||
test_xhr_timeout.html \
|
||||
test_blobConstructor.html \
|
||||
test_csp.html \
|
||||
test_csp.js \
|
||||
|
@ -108,9 +109,6 @@ MOCHITEST_FILES = \
|
|||
url_worker.js \
|
||||
$(NULL)
|
||||
|
||||
# Disabled for frequent failures (bug 841505, bug 842344, etc)
|
||||
# test_xhr_timeout.html \
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_chromeWorker.xul \
|
||||
test_chromeWorkerJSM.xul \
|
||||
|
|
|
@ -213,8 +213,7 @@ struct RequiredStringArg {
|
|||
return (void*) mBytes;
|
||||
}
|
||||
~RequiredStringArg() {
|
||||
if (mBytes)
|
||||
js_free(mBytes);
|
||||
js_free(mBytes);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -298,8 +298,7 @@ struct ClosureInfo
|
|||
~ClosureInfo() {
|
||||
if (closure)
|
||||
ffi_closure_free(closure);
|
||||
if (errResult)
|
||||
js_free(errResult);
|
||||
js_free(errResult);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3621,6 +3621,8 @@ EmitSingletonInitialiser(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *
|
|||
JS_STATIC_ASSERT(JSOP_NOP_LENGTH == 1);
|
||||
JS_STATIC_ASSERT(JSOP_POP_LENGTH == 1);
|
||||
|
||||
namespace {
|
||||
|
||||
class EmitLevelManager
|
||||
{
|
||||
BytecodeEmitter *bce;
|
||||
|
@ -3629,6 +3631,8 @@ class EmitLevelManager
|
|||
~EmitLevelManager() { bce->emitLevel--; }
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static bool
|
||||
EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
namespace {
|
||||
|
||||
class NameResolver
|
||||
{
|
||||
static const size_t MaxParents = 100;
|
||||
|
@ -325,6 +327,8 @@ class NameResolver
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
frontend::NameFunctions(JSContext *cx, ParseNode *pn)
|
||||
{
|
||||
|
|
|
@ -70,6 +70,8 @@ ParseNodeAllocator::freeNode(ParseNode *pn)
|
|||
freelist = pn;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* A work pool of ParseNodes. The work pool is a stack, chained together
|
||||
* by nodes' pn_next fields. We use this to avoid creating deep C++ stacks
|
||||
|
@ -104,6 +106,8 @@ class NodeStack {
|
|||
ParseNode *top;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/*
|
||||
* Push the children of |pn| on |stack|. Return true if |pn| itself could be
|
||||
* safely recycled, or false if it must be cleaned later (pn_used and pn_defn
|
||||
|
|
|
@ -333,8 +333,7 @@ TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options,
|
|||
|
||||
TokenStream::~TokenStream()
|
||||
{
|
||||
if (sourceMap)
|
||||
js_free(sourceMap);
|
||||
js_free(sourceMap);
|
||||
|
||||
JS_ASSERT_IF(originPrincipals, originPrincipals->refcount);
|
||||
}
|
||||
|
@ -847,8 +846,7 @@ TokenStream::getSourceMappingURL(bool isMultiline, bool shouldWarnDeprecated)
|
|||
|
||||
size_t sourceMapLength = tokenbuf.length();
|
||||
|
||||
if (sourceMap)
|
||||
js_free(sourceMap);
|
||||
js_free(sourceMap);
|
||||
sourceMap = cx->pod_malloc<jschar>(sourceMapLength + 1);
|
||||
if (!sourceMap)
|
||||
return false;
|
||||
|
|
|
@ -623,6 +623,8 @@ operator<=(Type lhs, VarType rhs)
|
|||
static inline MIRType ToMIRType(MIRType t) { return t; }
|
||||
static inline MIRType ToMIRType(VarType t) { return t.toMIRType(); }
|
||||
|
||||
namespace {
|
||||
|
||||
template <class VecT>
|
||||
class ABIArgIter
|
||||
{
|
||||
|
@ -683,6 +685,8 @@ class Signature
|
|||
RetType retType() const { return retType_; }
|
||||
};
|
||||
|
||||
} /* namespace anonymous */
|
||||
|
||||
static
|
||||
bool operator==(const Signature &lhs, const Signature &rhs)
|
||||
{
|
||||
|
@ -907,11 +911,11 @@ TypedArrayStoreType(ArrayBufferView::ViewType viewType)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
typedef Vector<PropertyName*,1> LabelVector;
|
||||
typedef Vector<MBasicBlock*,8> BlockVector;
|
||||
|
||||
namespace {
|
||||
|
||||
// ModuleCompiler encapsulates the compilation of an entire asm.js module. Over
|
||||
// the course of an ModuleCompiler object's lifetime, many FunctionCompiler
|
||||
// objects will be created and destroyed in sequence, one for each function in
|
||||
|
|
|
@ -96,8 +96,7 @@ struct BaselineStackBuilder
|
|||
}
|
||||
|
||||
~BaselineStackBuilder() {
|
||||
if (buffer_)
|
||||
js_free(buffer_);
|
||||
js_free(buffer_);
|
||||
}
|
||||
|
||||
bool init() {
|
||||
|
|
|
@ -422,8 +422,8 @@ BaselineCompiler::emitStackCheck()
|
|||
{
|
||||
Label skipCall;
|
||||
uintptr_t *limitAddr = &cx->runtime()->mainThread.ionStackLimit;
|
||||
masm.loadPtr(AbsoluteAddress(limitAddr), R0.scratchReg());
|
||||
masm.branchPtr(Assembler::AboveOrEqual, BaselineStackReg, R0.scratchReg(), &skipCall);
|
||||
masm.branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(limitAddr), BaselineStackReg,
|
||||
&skipCall);
|
||||
|
||||
prepareVMCall();
|
||||
if (!callVM(CheckOverRecursedInfo))
|
||||
|
|
|
@ -32,7 +32,7 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh)
|
|||
MInstruction *last = lsh;
|
||||
MDefinition *base = NULL;
|
||||
while (true) {
|
||||
if (last->useCount() != 1)
|
||||
if (!last->hasOneUse())
|
||||
break;
|
||||
|
||||
MUseIterator use = last->usesBegin();
|
||||
|
@ -61,7 +61,7 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh)
|
|||
if (displacement % elemSize != 0)
|
||||
return;
|
||||
|
||||
if (last->useCount() != 1)
|
||||
if (!last->hasOneUse())
|
||||
return;
|
||||
|
||||
MUseIterator use = last->usesBegin();
|
||||
|
|
|
@ -478,8 +478,7 @@ IonCompartment::IonCompartment(IonRuntime *rt)
|
|||
|
||||
IonCompartment::~IonCompartment()
|
||||
{
|
||||
if (stubCodes_)
|
||||
js_delete(stubCodes_);
|
||||
js_delete(stubCodes_);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1141,7 +1141,7 @@ IonBuilder::traverseBytecode()
|
|||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < popped.length(); i++) {
|
||||
// Call instructions can discard PassArg instructions. Ignore them.
|
||||
if (popped[i]->isPassArg() && popped[i]->useCount() == 0)
|
||||
if (popped[i]->isPassArg() && !popped[i]->hasUses())
|
||||
continue;
|
||||
|
||||
switch (op) {
|
||||
|
@ -4038,13 +4038,14 @@ IonBuilder::getInlineableGetPropertyCache(CallInfo &callInfo)
|
|||
return NULL;
|
||||
|
||||
MTypeBarrier *barrier = unbox->input()->toTypeBarrier();
|
||||
if (barrier->useCount() != 1)
|
||||
// Test if usecount() > 1
|
||||
if (!barrier->hasOneUse())
|
||||
return NULL;
|
||||
if (!barrier->input()->isGetPropertyCache())
|
||||
return NULL;
|
||||
|
||||
MGetPropertyCache *cache = barrier->input()->toGetPropertyCache();
|
||||
if (cache->useCount() > 1)
|
||||
if (cache->hasUses() && !cache->hasOneUse())
|
||||
return NULL;
|
||||
if (!CanInlineGetPropertyCache(cache, thisDef))
|
||||
return NULL;
|
||||
|
@ -4161,7 +4162,7 @@ IonBuilder::inlineTypeObjectFallback(CallInfo &callInfo, MBasicBlock *dispatchBl
|
|||
// 3. The MGetPropertyCache (and, if applicable, MTypeBarrier and MUnbox) only
|
||||
// have at most a single use.
|
||||
JS_ASSERT_IF(callInfo.fun()->isGetPropertyCache(), !cache->hasUses());
|
||||
JS_ASSERT_IF(callInfo.fun()->isUnbox(), cache->useCount() == 1);
|
||||
JS_ASSERT_IF(callInfo.fun()->isUnbox(), cache->hasOneUse());
|
||||
|
||||
// This means that no resume points yet capture the MGetPropertyCache,
|
||||
// so everything from the MGetPropertyCache up until the call is movable.
|
||||
|
|
|
@ -1807,8 +1807,7 @@ void
|
|||
ParallelIonCache::destroy()
|
||||
{
|
||||
DispatchIonCache::destroy();
|
||||
if (stubbedShapes_)
|
||||
js_delete(stubbedShapes_);
|
||||
js_delete(stubbedShapes_);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -586,10 +586,8 @@ struct IonBlockCounts
|
|||
}
|
||||
|
||||
void destroy() {
|
||||
if (successors_)
|
||||
js_free(successors_);
|
||||
if (code_)
|
||||
js_free(code_);
|
||||
js_free(successors_);
|
||||
js_free(code_);
|
||||
}
|
||||
|
||||
uint32_t id() const {
|
||||
|
@ -673,8 +671,7 @@ struct IonScriptCounts
|
|||
for (size_t i = 0; i < numBlocks_; i++)
|
||||
blocks_[i].destroy();
|
||||
js_free(blocks_);
|
||||
if (previous_)
|
||||
js_delete(previous_);
|
||||
js_delete(previous_);
|
||||
}
|
||||
|
||||
bool init(size_t numBlocks) {
|
||||
|
|
|
@ -1012,7 +1012,8 @@ MacroAssembler::loadBaselineOrIonNoArgCheck(Register script, Register dest, Exec
|
|||
void
|
||||
MacroAssembler::loadBaselineFramePtr(Register framePtr, Register dest)
|
||||
{
|
||||
movePtr(framePtr, dest);
|
||||
if (framePtr != dest)
|
||||
movePtr(framePtr, dest);
|
||||
subPtr(Imm32(BaselineFrame::Size()), dest);
|
||||
}
|
||||
|
||||
|
|
|
@ -259,6 +259,7 @@ jit::CheckLogging()
|
|||
" safepoints Safepoints\n"
|
||||
" pools Literal Pools (ARM only for now)\n"
|
||||
" cacheflush Instruction Cache flushes (ARM only for now)\n"
|
||||
" range Range Analysis\n"
|
||||
" logs C1 and JSON visualization logging\n"
|
||||
" trace Generate calls to js::jit::Trace() for effectful instructions\n"
|
||||
" all Everything\n"
|
||||
|
|
|
@ -559,9 +559,14 @@ ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp)
|
|||
if (rhs->isConstant())
|
||||
return;
|
||||
|
||||
if (lhs->isConstant() ||
|
||||
(rhs->defUseCount() == 1 && lhs->defUseCount() > 1))
|
||||
{
|
||||
// lhs and rhs are used by the commutative operator. If they have any
|
||||
// *other* uses besides, try to reorder to avoid clobbering them. To
|
||||
// be fully precise, we should check whether this is the *last* use,
|
||||
// but checking hasOneDefUse() is a decent approximation which doesn't
|
||||
// require any extra analysis.
|
||||
JS_ASSERT(lhs->defUseCount() > 0);
|
||||
JS_ASSERT(rhs->defUseCount() > 0);
|
||||
if (lhs->isConstant() || (rhs->hasOneDefUse() && !lhs->hasOneDefUse())) {
|
||||
*rhsp = lhs;
|
||||
*lhsp = rhs;
|
||||
}
|
||||
|
@ -1118,7 +1123,7 @@ LIRGenerator::visitSqrt(MSqrt *ins)
|
|||
MDefinition *num = ins->num();
|
||||
JS_ASSERT(num->type() == MIRType_Double);
|
||||
LSqrtD *lir = new LSqrtD(useRegisterAtStart(num));
|
||||
return defineReuseInput(lir, ins, 0);
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -273,6 +273,35 @@ MDefinition::defUseCount() const
|
|||
return count;
|
||||
}
|
||||
|
||||
bool
|
||||
MDefinition::hasOneUse() const
|
||||
{
|
||||
MUseIterator i(uses_.begin());
|
||||
if (i == uses_.end())
|
||||
return false;
|
||||
i++;
|
||||
return i == uses_.end();
|
||||
}
|
||||
|
||||
bool
|
||||
MDefinition::hasOneDefUse() const
|
||||
{
|
||||
bool hasOneDefUse = false;
|
||||
for (MUseIterator i(uses_.begin()); i != uses_.end(); i++) {
|
||||
if (!(*i)->consumer()->isDefinition())
|
||||
continue;
|
||||
|
||||
// We already have a definition use. So 1+
|
||||
if (hasOneDefUse)
|
||||
return false;
|
||||
|
||||
// We saw one definition. Loop to test if there is another.
|
||||
hasOneDefUse = true;
|
||||
}
|
||||
|
||||
return hasOneDefUse;
|
||||
}
|
||||
|
||||
MUseIterator
|
||||
MDefinition::removeUse(MUseIterator use)
|
||||
{
|
||||
|
@ -856,7 +885,7 @@ MPhi::addInputSlow(MDefinition *ins, bool *ptypeChange)
|
|||
uint32_t
|
||||
MPrepareCall::argc() const
|
||||
{
|
||||
JS_ASSERT(useCount() == 1);
|
||||
JS_ASSERT(hasOneUse());
|
||||
MCall *call = usesBegin()->consumer()->toDefinition()->toCall();
|
||||
return call->numStackArgs();
|
||||
}
|
||||
|
|
|
@ -480,6 +480,13 @@ class MDefinition : public MNode
|
|||
// (only counting MDefinitions, ignoring MResumePoints)
|
||||
size_t defUseCount() const;
|
||||
|
||||
// Test whether this MDefinition has exactly one use.
|
||||
bool hasOneUse() const;
|
||||
|
||||
// Test whether this MDefinition has exactly one use.
|
||||
// (only counting MDefinitions, ignoring MResumePoints)
|
||||
bool hasOneDefUse() const;
|
||||
|
||||
bool hasUses() const {
|
||||
return !uses_.empty();
|
||||
}
|
||||
|
@ -3946,11 +3953,9 @@ class MBeta : public MUnaryInstruction
|
|||
{
|
||||
private:
|
||||
const Range *comparison_;
|
||||
MDefinition *val_;
|
||||
MBeta(MDefinition *val, const Range *comp)
|
||||
: MUnaryInstruction(val),
|
||||
comparison_(comp),
|
||||
val_(val)
|
||||
comparison_(comp)
|
||||
{
|
||||
setResultType(val->type());
|
||||
setResultTypeSet(val->resultTypeSet());
|
||||
|
|
|
@ -358,12 +358,12 @@ Range::unionWith(const Range *other)
|
|||
if (lower_infinite_ || other->lower_infinite_)
|
||||
makeLowerInfinite();
|
||||
else
|
||||
setLower(Min(lower_, other->lower_));
|
||||
setLowerInit(Min(lower_, other->lower_));
|
||||
|
||||
if (upper_infinite_ || other->upper_infinite_)
|
||||
makeUpperInfinite();
|
||||
else
|
||||
setUpper(Max(upper_, other->upper_));
|
||||
setUpperInit(Max(upper_, other->upper_));
|
||||
|
||||
decimal_ = decimal;
|
||||
max_exponent_ = max_exponent;
|
||||
|
@ -800,7 +800,7 @@ MBeta::computeRange()
|
|||
{
|
||||
bool emptyRange = false;
|
||||
|
||||
Range *range = Range::intersect(val_->range(), comparison_, &emptyRange);
|
||||
Range *range = Range::intersect(getOperand(0)->range(), comparison_, &emptyRange);
|
||||
if (emptyRange) {
|
||||
IonSpew(IonSpew_Range, "Marking block for inst %d unexitable", id());
|
||||
block()->setEarlyAbort();
|
||||
|
|
|
@ -297,7 +297,7 @@ UnreachableCodeElimination::removeUnmarkedBlocksAndClearDominators()
|
|||
MCall *call = iter->toCall();
|
||||
for (size_t i = 0; i < call->numStackArgs(); i++) {
|
||||
JS_ASSERT(call->getArg(i)->isPassArg());
|
||||
JS_ASSERT(call->getArg(i)->defUseCount() == 1);
|
||||
JS_ASSERT(call->getArg(i)->hasOneDefUse());
|
||||
MPassArg *arg = call->getArg(i)->toPassArg();
|
||||
arg->replaceAllUsesWith(arg->getArgument());
|
||||
}
|
||||
|
|
|
@ -343,8 +343,8 @@ bool
|
|||
CodeGeneratorARM::visitSqrtD(LSqrtD *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
JS_ASSERT(input == ToFloatRegister(ins->output()));
|
||||
masm.ma_vsqrt(input, input);
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
masm.ma_vsqrt(input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::DoubleSignificandBits;
|
||||
using mozilla::FloorLog2;
|
||||
using mozilla::NegativeInfinity;
|
||||
using mozilla::SpecificNaN;
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
@ -420,9 +423,9 @@ CodeGeneratorX86Shared::visitAbsD(LAbsD *ins)
|
|||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
JS_ASSERT(input == ToFloatRegister(ins->output()));
|
||||
masm.xorpd(ScratchFloatReg, ScratchFloatReg);
|
||||
masm.subsd(input, ScratchFloatReg); // negate the sign bit.
|
||||
masm.andpd(ScratchFloatReg, input); // s & ~s
|
||||
// Load a value which is all ones except for the sign bit.
|
||||
masm.loadConstantDouble(SpecificNaN(0, DoubleSignificandBits), ScratchFloatReg);
|
||||
masm.andpd(ScratchFloatReg, input);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -430,8 +433,8 @@ bool
|
|||
CodeGeneratorX86Shared::visitSqrtD(LSqrtD *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
JS_ASSERT(input == ToFloatRegister(ins->output()));
|
||||
masm.sqrtsd(input, input);
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
masm.sqrtsd(input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -439,15 +442,12 @@ bool
|
|||
CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
Register scratch = ToRegister(ins->temp());
|
||||
JS_ASSERT(input == ToFloatRegister(ins->output()));
|
||||
|
||||
const uint32_t NegInfinityFloatBits = 0xFF800000;
|
||||
Label done, sqrt;
|
||||
|
||||
// Branch if not -Infinity.
|
||||
masm.move32(Imm32(NegInfinityFloatBits), scratch);
|
||||
masm.loadFloatAsDouble(scratch, ScratchFloatReg);
|
||||
masm.loadConstantDouble(NegativeInfinity(), ScratchFloatReg);
|
||||
masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, input, ScratchFloatReg, &sqrt);
|
||||
|
||||
// Math.pow(-Infinity, 0.5) == Infinity.
|
||||
|
|
|
@ -157,21 +157,17 @@ class LModPowTwoI : public LInstructionHelper<1,1,0>
|
|||
};
|
||||
|
||||
// Double raised to a half power.
|
||||
class LPowHalfD : public LInstructionHelper<1, 1, 1>
|
||||
class LPowHalfD : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(PowHalfD)
|
||||
LPowHalfD(const LAllocation &input, const LDefinition &temp) {
|
||||
LPowHalfD(const LAllocation &input) {
|
||||
setOperand(0, input);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
const LAllocation *input() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition *temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
const LDefinition *output() {
|
||||
return getDef(0);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ LIRGeneratorX86Shared::visitPowHalf(MPowHalf *ins)
|
|||
{
|
||||
MDefinition *input = ins->input();
|
||||
JS_ASSERT(input->type() == MIRType_Double);
|
||||
LPowHalfD *lir = new LPowHalfD(useRegisterAtStart(input), temp());
|
||||
LPowHalfD *lir = new LPowHalfD(useRegisterAtStart(input));
|
||||
return defineReuseInput(lir, ins, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ ICCompare_Int32::Compiler::generateStubCode(MacroAssembler &masm)
|
|||
|
||||
// Directly compare the int32 payload of R0 and R1.
|
||||
Assembler::Condition cond = JSOpToCondition(op, /* signed = */true);
|
||||
masm.xorl(ScratchReg, ScratchReg);
|
||||
masm.cmpl(R0.valueReg(), R1.valueReg());
|
||||
masm.setCC(cond, ScratchReg);
|
||||
masm.movzxbl(ScratchReg, ScratchReg);
|
||||
|
||||
// Box the result and return
|
||||
masm.boxValue(JSVAL_TYPE_BOOLEAN, ScratchReg, R0.valueReg());
|
||||
|
|
|
@ -314,6 +314,6 @@ Assembler::Condition
|
|||
MacroAssemblerX64::testNegativeZero(const FloatRegister ®, const Register &scratch)
|
||||
{
|
||||
movq(reg, scratch);
|
||||
subq(Imm32(1), scratch);
|
||||
cmpq(scratch, Imm32(1));
|
||||
return Overflow;
|
||||
}
|
||||
|
|
|
@ -348,8 +348,6 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void *
|
|||
|
||||
masm.push(r10);
|
||||
masm.subl(Imm32(1), rcx);
|
||||
|
||||
masm.testl(rcx, rcx);
|
||||
masm.j(Assembler::NonZero, &undefLoopTop);
|
||||
}
|
||||
|
||||
|
@ -358,19 +356,14 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void *
|
|||
masm.lea(Operand(b), rcx);
|
||||
|
||||
// Push arguments, |nargs| + 1 times (to include |this|).
|
||||
masm.addl(Imm32(1), r8);
|
||||
{
|
||||
Label copyLoopTop, initialSkip;
|
||||
|
||||
masm.jump(&initialSkip);
|
||||
Label copyLoopTop;
|
||||
|
||||
masm.bind(©LoopTop);
|
||||
masm.push(Operand(rcx, 0x0));
|
||||
masm.subq(Imm32(sizeof(Value)), rcx);
|
||||
masm.subl(Imm32(1), r8);
|
||||
masm.bind(&initialSkip);
|
||||
|
||||
masm.push(Operand(rcx, 0x0));
|
||||
|
||||
masm.testl(r8, r8);
|
||||
masm.j(Assembler::NonZero, ©LoopTop);
|
||||
}
|
||||
|
||||
|
|
|
@ -342,8 +342,6 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void *
|
|||
masm.push(ebx); // type(undefined);
|
||||
masm.push(edi); // payload(undefined);
|
||||
masm.subl(Imm32(1), ecx);
|
||||
|
||||
masm.testl(ecx, ecx);
|
||||
masm.j(Assembler::NonZero, &undefLoopTop);
|
||||
}
|
||||
|
||||
|
@ -354,20 +352,15 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void *
|
|||
masm.lea(Operand(b), ecx);
|
||||
|
||||
// Push arguments, |nargs| + 1 times (to include |this|).
|
||||
masm.addl(Imm32(1), esi);
|
||||
{
|
||||
Label copyLoopTop, initialSkip;
|
||||
|
||||
masm.jump(&initialSkip);
|
||||
Label copyLoopTop;
|
||||
|
||||
masm.bind(©LoopTop);
|
||||
masm.subl(Imm32(sizeof(Value)), ecx);
|
||||
masm.subl(Imm32(1), esi);
|
||||
masm.bind(&initialSkip);
|
||||
|
||||
masm.push(Operand(ecx, sizeof(Value)/2));
|
||||
masm.push(Operand(ecx, 0x0));
|
||||
|
||||
masm.testl(esi, esi);
|
||||
masm.subl(Imm32(sizeof(Value)), ecx);
|
||||
masm.subl(Imm32(1), esi);
|
||||
masm.j(Assembler::NonZero, ©LoopTop);
|
||||
}
|
||||
|
||||
|
|
|
@ -2875,6 +2875,8 @@ JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AutoHoldZone
|
||||
{
|
||||
public:
|
||||
|
@ -2895,6 +2897,8 @@ class AutoHoldZone
|
|||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
|
||||
JS::OnNewGlobalHookOption hookOption,
|
||||
|
@ -4713,6 +4717,8 @@ ReadCompleteFile(JSContext *cx, FILE *fp, FileContents &buffer)
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AutoFile
|
||||
{
|
||||
FILE *fp_;
|
||||
|
@ -4734,6 +4740,8 @@ class AutoFile
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/*
|
||||
* Open a source file for reading. Supports "-" and NULL to mean stdin. The
|
||||
* return value must be fclosed unless it is stdin.
|
||||
|
|
|
@ -831,8 +831,7 @@ js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback,
|
|||
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
if (message)
|
||||
js_free(message);
|
||||
js_free(message);
|
||||
if (report.messageArgs) {
|
||||
/*
|
||||
* js_ExpandErrorArguments owns its messageArgs only if it had to
|
||||
|
@ -845,8 +844,7 @@ js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback,
|
|||
}
|
||||
js_free((void *)report.messageArgs);
|
||||
}
|
||||
if (report.ucmessage)
|
||||
js_free((void *)report.ucmessage);
|
||||
js_free((void *)report.ucmessage);
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
@ -876,10 +874,8 @@ js_ReportErrorNumberUCArray(JSContext *cx, unsigned flags, JSErrorCallback callb
|
|||
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
if (message)
|
||||
js_free(message);
|
||||
if (report.ucmessage)
|
||||
js_free((void *)report.ucmessage);
|
||||
js_free(message);
|
||||
js_free((void *)report.ucmessage);
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
|
|
@ -4023,6 +4023,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)
|
|||
rt->gcLastGCTime = PRMJ_Now();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* ...while this class is to be used only for garbage collection. */
|
||||
class AutoGCSession : AutoTraceSession {
|
||||
public:
|
||||
|
@ -4030,6 +4032,8 @@ class AutoGCSession : AutoTraceSession {
|
|||
~AutoGCSession();
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/* Start a new heap session. */
|
||||
AutoTraceSession::AutoTraceSession(JSRuntime *rt, js::HeapState heapState)
|
||||
: runtime(rt),
|
||||
|
@ -4173,6 +4177,8 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason)
|
|||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AutoGCSlice {
|
||||
public:
|
||||
AutoGCSlice(JSRuntime *rt);
|
||||
|
@ -4182,6 +4188,8 @@ class AutoGCSlice {
|
|||
JSRuntime *runtime;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
AutoGCSlice::AutoGCSlice(JSRuntime *rt)
|
||||
: runtime(rt)
|
||||
{
|
||||
|
@ -4505,6 +4513,8 @@ ShouldCleanUpEverything(JSRuntime *rt, JS::gcreason::Reason reason, JSGCInvocati
|
|||
gckind == GC_SHRINK;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
class AutoDisableStoreBuffer
|
||||
{
|
||||
|
@ -4528,6 +4538,8 @@ struct AutoDisableStoreBuffer
|
|||
};
|
||||
#endif
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static void
|
||||
Collect(JSRuntime *rt, bool incremental, int64_t budget,
|
||||
JSGCInvocationKind gckind, JS::gcreason::Reason reason)
|
||||
|
|
|
@ -568,6 +568,8 @@ TypeSet::unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc)
|
|||
// TypeSet constraints
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
|
||||
/* Standard subset constraint, propagate all types from one set to another. */
|
||||
class TypeConstraintSubset : public TypeConstraint
|
||||
{
|
||||
|
@ -589,6 +591,8 @@ class TypeConstraintSubset : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addSubset(JSContext *cx, TypeSet *target)
|
||||
{
|
||||
|
@ -602,6 +606,8 @@ HeapTypeSet::addSubset(JSContext *cx, TypeSet *target)
|
|||
add(cx, cx->typeLifoAlloc().new_<TypeConstraintSubset>(target));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
enum PropertyAccessKind {
|
||||
PROPERTY_WRITE,
|
||||
PROPERTY_READ,
|
||||
|
@ -641,6 +647,8 @@ typedef TypeConstraintProp<PROPERTY_WRITE> TypeConstraintSetProperty;
|
|||
typedef TypeConstraintProp<PROPERTY_READ> TypeConstraintGetProperty;
|
||||
typedef TypeConstraintProp<PROPERTY_READ_EXISTING> TypeConstraintGetPropertyExisting;
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
StackTypeSet *target, jsid id)
|
||||
|
@ -669,6 +677,8 @@ HeapTypeSet::addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
add(cx, cx->typeLifoAlloc().new_<TypeConstraintGetProperty>(script, pc, target, id));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Constraints for updating the 'this' types of callees on CALLPROP/CALLELEM.
|
||||
* These are derived from the types on the properties themselves, rather than
|
||||
|
@ -701,6 +711,8 @@ class TypeConstraintCallProp : public TypeConstraint
|
|||
typedef TypeConstraintCallProp<PROPERTY_READ> TypeConstraintCallProperty;
|
||||
typedef TypeConstraintCallProp<PROPERTY_READ_EXISTING> TypeConstraintCallPropertyExisting;
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
HeapTypeSet::addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid id)
|
||||
{
|
||||
|
@ -716,6 +728,8 @@ HeapTypeSet::addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, js
|
|||
add(cx, cx->typeLifoAlloc().new_<TypeConstraintCallProperty>(script, callpc, id));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Constraints for generating 'set' property constraints on a SETELEM only if
|
||||
* the element type may be a number. For SETELEM we only account for integer
|
||||
|
@ -745,6 +759,8 @@ class TypeConstraintSetElement : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
StackTypeSet *objectTypes, StackTypeSet *valueTypes)
|
||||
|
@ -753,6 +769,8 @@ StackTypeSet::addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
valueTypes));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Constraints for watching call edges as they are discovered and invoking native
|
||||
* function handlers, adding constraints for arguments, receiver objects and the
|
||||
|
@ -773,12 +791,16 @@ class TypeConstraintCall : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addCall(JSContext *cx, TypeCallsite *site)
|
||||
{
|
||||
add(cx, cx->analysisLifoAlloc().new_<TypeConstraintCall>(site));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Constraints for arithmetic operations. */
|
||||
class TypeConstraintArith : public TypeConstraint
|
||||
{
|
||||
|
@ -804,6 +826,8 @@ class TypeConstraintArith : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addArith(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target,
|
||||
TypeSet *other)
|
||||
|
@ -811,6 +835,8 @@ StackTypeSet::addArith(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet
|
|||
add(cx, cx->analysisLifoAlloc().new_<TypeConstraintArith>(script, pc, target, other));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Subset constraint which transforms primitive values into appropriate objects. */
|
||||
class TypeConstraintTransformThis : public TypeConstraint
|
||||
{
|
||||
|
@ -828,12 +854,16 @@ class TypeConstraintTransformThis : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addTransformThis(JSContext *cx, JSScript *script, TypeSet *target)
|
||||
{
|
||||
add(cx, cx->analysisLifoAlloc().new_<TypeConstraintTransformThis>(script, target));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Constraint which adds a particular type to the 'this' types of all
|
||||
* discovered scripted functions.
|
||||
|
@ -856,6 +886,8 @@ class TypeConstraintPropagateThis : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
Type type, StackTypeSet *types)
|
||||
|
@ -863,6 +895,8 @@ StackTypeSet::addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
add(cx, cx->analysisLifoAlloc().new_<TypeConstraintPropagateThis>(script, pc, type, types));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Subset constraint which filters out primitive types. */
|
||||
class TypeConstraintFilterPrimitive : public TypeConstraint
|
||||
{
|
||||
|
@ -884,6 +918,8 @@ class TypeConstraintFilterPrimitive : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
HeapTypeSet::addFilterPrimitives(JSContext *cx, TypeSet *target)
|
||||
{
|
||||
|
@ -994,6 +1030,8 @@ void ScriptAnalysis::breakTypeBarriersSSA(JSContext *cx, const SSAValue &v)
|
|||
breakTypeBarriers(cx, offset, true);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Subset constraint for property reads and argument passing which can add type
|
||||
* barriers on the read instead of passing types along.
|
||||
|
@ -1021,6 +1059,8 @@ class TypeConstraintSubsetBarrier : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
StackTypeSet::addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target)
|
||||
{
|
||||
|
@ -1634,6 +1674,8 @@ TypeConstraintTransformThis::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
// Freeze constraints
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
|
||||
/* Constraint which triggers recompilation of a script if any type is added to a type set. */
|
||||
class TypeConstraintFreeze : public TypeConstraint
|
||||
{
|
||||
|
@ -1659,6 +1701,8 @@ class TypeConstraintFreeze : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
HeapTypeSet::addFreeze(JSContext *cx)
|
||||
{
|
||||
|
@ -1754,6 +1798,8 @@ StackTypeSet::mightBeType(JSValueType type)
|
|||
return baseFlags() & PrimitiveTypeFlag(type);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Constraint which triggers recompilation if an object acquires particular flags. */
|
||||
class TypeConstraintFreezeObjectFlags : public TypeConstraint
|
||||
{
|
||||
|
@ -1784,6 +1830,8 @@ class TypeConstraintFreezeObjectFlags : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
StackTypeSet::hasObjectFlags(JSContext *cx, TypeObjectFlags flags)
|
||||
{
|
||||
|
@ -1881,6 +1929,8 @@ HeapTypeSet::WatchObjectStateChange(JSContext *cx, TypeObject *obj)
|
|||
0));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class TypeConstraintFreezeOwnProperty : public TypeConstraint
|
||||
{
|
||||
public:
|
||||
|
@ -1908,6 +1958,8 @@ class TypeConstraintFreezeOwnProperty : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static void
|
||||
CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, HandleFunction fun);
|
||||
|
||||
|
@ -2217,6 +2269,8 @@ AddPendingRecompile(JSContext *cx, JSScript *script)
|
|||
cx->compartment()->types.addPendingRecompile(cx, script);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* As for TypeConstraintFreeze, but describes an implicit freeze constraint
|
||||
* added for stack types within a script. Applies to all compilations of the
|
||||
|
@ -2243,6 +2297,8 @@ class TypeConstraintFreezeStack : public TypeConstraint
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// TypeCompartment
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -4745,6 +4801,8 @@ ScriptAnalysis::analyzeTypes(JSContext *cx)
|
|||
TypeScript::AddFreezeConstraints(cx, script_);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Persistent constraint clearing out newScript and definite properties from
|
||||
* an object should a property on another object get a getter or setter.
|
||||
|
@ -4777,6 +4835,8 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint
|
|||
void newType(JSContext *cx, TypeSet *source, Type type) {}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static bool
|
||||
AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, jsid id)
|
||||
{
|
||||
|
@ -4799,6 +4859,8 @@ AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, j
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Constraint which clears definite properties on an object should a type set
|
||||
* contain any types other than a single object.
|
||||
|
@ -4835,6 +4897,8 @@ struct NewScriptPropertiesState
|
|||
{}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static bool
|
||||
AnalyzePoppedThis(JSContext *cx, SSAUseChain *use,
|
||||
TypeObject *type, JSFunction *fun, NewScriptPropertiesState &state);
|
||||
|
@ -6386,17 +6450,10 @@ JSCompartment::sweepNewTypeObjectTable(TypeObjectSet &table)
|
|||
|
||||
TypeCompartment::~TypeCompartment()
|
||||
{
|
||||
if (pendingArray)
|
||||
js_free(pendingArray);
|
||||
|
||||
if (arrayTypeTable)
|
||||
js_delete(arrayTypeTable);
|
||||
|
||||
if (objectTypeTable)
|
||||
js_delete(objectTypeTable);
|
||||
|
||||
if (allocationSiteTable)
|
||||
js_delete(allocationSiteTable);
|
||||
js_free(pendingArray);
|
||||
js_delete(arrayTypeTable);
|
||||
js_delete(objectTypeTable);
|
||||
js_delete(allocationSiteTable);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
|
|
@ -1166,6 +1166,8 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class SingleStringPredicate {
|
||||
Handle<JSFlatString*> str;
|
||||
public:
|
||||
|
@ -1175,6 +1177,8 @@ public:
|
|||
bool matchesAtMostOne() { return true; }
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
js_SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id)
|
||||
{
|
||||
|
@ -1193,6 +1197,8 @@ js_SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index)
|
|||
return js_SuppressDeletedProperty(cx, obj, id);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class IndexRangePredicate {
|
||||
uint32_t begin, end;
|
||||
|
||||
|
@ -1207,6 +1213,8 @@ class IndexRangePredicate {
|
|||
bool matchesAtMostOne() { return false; }
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
js_SuppressDeletedElements(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end)
|
||||
{
|
||||
|
|
|
@ -85,6 +85,8 @@ ComputeAccurateDecimalInteger(ThreadSafeContext *cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class BinaryDigitReader
|
||||
{
|
||||
const int base; /* Base of number; must be a power of 2 */
|
||||
|
@ -122,6 +124,8 @@ class BinaryDigitReader
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/*
|
||||
* The fast result might also have been inaccurate for power-of-two bases. This
|
||||
* happens if the addition in value * 2 + digit causes a round-down to an even
|
||||
|
@ -532,8 +536,7 @@ ToCStringBuf::ToCStringBuf() :dbuf(NULL)
|
|||
|
||||
ToCStringBuf::~ToCStringBuf()
|
||||
{
|
||||
if (dbuf)
|
||||
js_free(dbuf);
|
||||
js_free(dbuf);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
|
|
@ -1868,10 +1868,8 @@ struct JSObject::TradeGutsReserved {
|
|||
|
||||
~TradeGutsReserved()
|
||||
{
|
||||
if (newaslots)
|
||||
js_free(newaslots);
|
||||
if (newbslots)
|
||||
js_free(newbslots);
|
||||
js_free(newaslots);
|
||||
js_free(newbslots);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ Quote(JSContext *cx, StringBuffer &sb, JSString *str)
|
|||
return sb.append('"');
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class StringifyContext
|
||||
{
|
||||
public:
|
||||
|
@ -134,6 +136,8 @@ class StringifyContext
|
|||
uint32_t depth;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static bool Str(JSContext *cx, const Value &v, StringifyContext *scx);
|
||||
|
||||
static bool
|
||||
|
@ -151,6 +155,8 @@ WriteIndent(JSContext *cx, StringifyContext *scx, uint32_t limit)
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename KeyType>
|
||||
class KeyStringifier {
|
||||
};
|
||||
|
@ -171,6 +177,8 @@ class KeyStringifier<HandleId> {
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
/*
|
||||
* ES5 15.12.3 Str, steps 2-4, extracted to enable preprocessing of property
|
||||
* values when stringifying objects in JO.
|
||||
|
|
|
@ -1087,6 +1087,8 @@ GetBlockChainAtPC(JSContext *cx, JSScript *script, jsbytecode *pc)
|
|||
return blockChain;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class PCStack
|
||||
{
|
||||
jsbytecode **stack;
|
||||
|
@ -1100,6 +1102,8 @@ class PCStack
|
|||
jsbytecode *operator[](int i) const;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
PCStack::~PCStack()
|
||||
{
|
||||
js_free(stack);
|
||||
|
|
|
@ -1053,11 +1053,7 @@ static int GrowStuff(SprintfState *ss, const char *sp, uint32_t len)
|
|||
if (off + len >= ss->maxlen) {
|
||||
/* Grow the buffer */
|
||||
newlen = ss->maxlen + ((len > 32) ? len : 32);
|
||||
if (ss->base) {
|
||||
newbase = (char*) js_realloc(ss->base, newlen);
|
||||
} else {
|
||||
newbase = (char*) js_malloc(newlen);
|
||||
}
|
||||
newbase = (char*) js_realloc(ss->base, newlen);
|
||||
if (!newbase) {
|
||||
/* Ran out of memory */
|
||||
return -1;
|
||||
|
@ -1109,9 +1105,7 @@ JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap)
|
|||
ss.maxlen = 0;
|
||||
rv = dosprintf(&ss, fmt, ap);
|
||||
if (rv < 0) {
|
||||
if (ss.base) {
|
||||
js_free(ss.base);
|
||||
}
|
||||
js_free(ss.base);
|
||||
return 0;
|
||||
}
|
||||
return ss.base;
|
||||
|
@ -1208,9 +1202,7 @@ JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap
|
|||
}
|
||||
rv = dosprintf(&ss, fmt, ap);
|
||||
if (rv < 0) {
|
||||
if (ss.base) {
|
||||
js_free(ss.base);
|
||||
}
|
||||
js_free(ss.base);
|
||||
return 0;
|
||||
}
|
||||
return ss.base;
|
||||
|
|
|
@ -746,6 +746,8 @@ FunctionProxyObject::constructOrUndefined() const
|
|||
return getSlot(CONSTRUCT_SLOT);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Derived class for all scripted indirect proxy handlers. */
|
||||
class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
{
|
||||
|
@ -791,6 +793,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
|||
static ScriptedIndirectProxyHandler singleton;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static int sScriptedIndirectProxyHandlerFamily = 0;
|
||||
|
||||
ScriptedIndirectProxyHandler::ScriptedIndirectProxyHandler()
|
||||
|
|
|
@ -120,6 +120,8 @@ typedef AutoValueVector NodeVector;
|
|||
return false; \
|
||||
JS_END_MACRO
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Builder class that constructs JavaScript AST node objects. See:
|
||||
*
|
||||
|
@ -615,6 +617,8 @@ class NodeBuilder
|
|||
bool propertyPattern(HandleValue key, HandleValue patt, TokenPos *pos, MutableHandleValue dst);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
NodeBuilder::newNode(ASTType type, TokenPos *pos, MutableHandleObject dst)
|
||||
{
|
||||
|
|
|
@ -2979,6 +2979,8 @@ DebuggerScript_getOffsetLine(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class BytecodeRangeWithPosition : private BytecodeRange
|
||||
{
|
||||
public:
|
||||
|
@ -3207,6 +3209,8 @@ class FlowGraphSummary {
|
|||
Vector<Entry> entries_;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static bool
|
||||
DebuggerScript_getAllOffsets(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
|
|
|
@ -1004,6 +1004,8 @@ JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc)
|
|||
js_delete(desc);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AutoPropertyDescArray
|
||||
{
|
||||
JSContext *cx_;
|
||||
|
@ -1032,6 +1034,8 @@ class AutoPropertyDescArray
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static const char *
|
||||
FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes)
|
||||
{
|
||||
|
|
|
@ -393,8 +393,7 @@ RegExpShared::~RegExpShared()
|
|||
#if ENABLE_YARR_JIT
|
||||
codeBlock.release();
|
||||
#endif
|
||||
if (bytecode)
|
||||
js_delete<BytecodePattern>(bytecode);
|
||||
js_delete<BytecodePattern>(bytecode);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -390,8 +390,7 @@ JSRuntime::~JSRuntime()
|
|||
mainThread.removeFromThreadList();
|
||||
|
||||
#ifdef JS_WORKER_THREADS
|
||||
if (workerThreadState)
|
||||
js_delete(workerThreadState);
|
||||
js_delete(workerThreadState);
|
||||
|
||||
JS_ASSERT(!exclusiveAccessOwner);
|
||||
if (exclusiveAccessLock)
|
||||
|
@ -451,8 +450,7 @@ JSRuntime::~JSRuntime()
|
|||
#endif
|
||||
js_delete(execAlloc_); /* Delete after ionRuntime_. */
|
||||
|
||||
if (ionPcScriptCache)
|
||||
js_delete(ionPcScriptCache);
|
||||
js_delete(ionPcScriptCache);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
gcStoreBuffer.disable();
|
||||
|
|
|
@ -1138,6 +1138,8 @@ ScopeIterKey::match(ScopeIterKey si1, ScopeIterKey si2)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* DebugScopeProxy is the handler for DebugScopeObject proxy objects. Having a
|
||||
* custom handler (rather than trying to reuse js::Wrapper) gives us several
|
||||
|
@ -1532,6 +1534,8 @@ class DebugScopeProxy : public BaseProxyHandler
|
|||
}
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
int DebugScopeProxy::family = 0;
|
||||
DebugScopeProxy DebugScopeProxy::singleton;
|
||||
|
||||
|
|
|
@ -966,12 +966,14 @@ JSStructuredCloneReader::checkDouble(double d)
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class Chars {
|
||||
JSContext *cx;
|
||||
jschar *p;
|
||||
public:
|
||||
Chars(JSContext *cx) : cx(cx), p(NULL) {}
|
||||
~Chars() { if (p) js_free(p); }
|
||||
~Chars() { js_free(p); }
|
||||
|
||||
bool allocate(size_t len) {
|
||||
JS_ASSERT(!p);
|
||||
|
@ -987,6 +989,8 @@ class Chars {
|
|||
void forget() { p = NULL; }
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
JSString *
|
||||
JSStructuredCloneReader::readString(uint32_t nchars)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ using namespace js;
|
|||
// Once the worker's state is set to |TERMINATING|, the worker will
|
||||
// exit as soon as its queue is empty.
|
||||
|
||||
const size_t WORKER_THREAD_STACK_SIZE = 1*1024*1024;
|
||||
static const size_t WORKER_THREAD_STACK_SIZE = 1*1024*1024;
|
||||
|
||||
class js::ThreadPoolWorker : public Monitor
|
||||
{
|
||||
|
|
|
@ -1407,8 +1407,6 @@ template<> inline const bool ElementTypeMayBeDouble<uint32_t>() { return true; }
|
|||
template<> inline const bool ElementTypeMayBeDouble<float>() { return true; }
|
||||
template<> inline const bool ElementTypeMayBeDouble<double>() { return true; }
|
||||
|
||||
template<typename NativeType> class TypedArrayObjectTemplate;
|
||||
|
||||
template<typename ElementType>
|
||||
static inline JSObject *
|
||||
NewArray(JSContext *cx, uint32_t nelements);
|
||||
|
@ -1425,6 +1423,8 @@ InitArrayBufferViewDataPointer(JSObject *obj, ArrayBufferObject *buffer, size_t
|
|||
PostBarrierTypedArrayObject(obj);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename NativeType>
|
||||
class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
{
|
||||
|
@ -2619,6 +2619,8 @@ class Uint8ClampedArrayObject : public TypedArrayObjectTemplate<uint8_clamped> {
|
|||
static const JSFunctionSpec jsfuncs[];
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
ArrayBufferObject::createTypedArrayFromBufferImpl(JSContext *cx, CallArgs args)
|
||||
|
@ -2682,6 +2684,8 @@ TypedArrayObjectTemplate<NativeType>::copyIndexToValue(JSObject *tarray, uint32_
|
|||
vp.setInt32(getIndex(tarray, index));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// and we need to specialize for 32-bit integers and floats
|
||||
template<>
|
||||
void
|
||||
|
@ -2739,6 +2743,8 @@ TypedArrayObjectTemplate<double>::copyIndexToValue(JSObject *tarray, uint32_t in
|
|||
vp.setDouble(JS_CANONICALIZE_NAN(val));
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
static NewObjectKind
|
||||
DataViewNewObjectKind(JSContext *cx, uint32_t byteLength, JSObject *proto)
|
||||
{
|
||||
|
|
|
@ -82,8 +82,7 @@ class OwnPtr {
|
|||
OwnPtr(PassOwnPtr<T> p) : ptr(p.get()) { }
|
||||
|
||||
~OwnPtr() {
|
||||
if (ptr)
|
||||
js_delete(ptr);
|
||||
js_delete(ptr);
|
||||
}
|
||||
|
||||
OwnPtr<T> &operator=(PassOwnPtr<T> p) {
|
||||
|
|
|
@ -318,12 +318,12 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
|||
nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
|
||||
initialized = true;
|
||||
|
||||
// Set the priorites for candidate type preferences
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx",100);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx",105);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.prflx",99);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.host",125);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.relayed",126);
|
||||
// Set the priorites for candidate type preferences.
|
||||
// These numbers come from RFC 5245 S. 4.1.2.2
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx", 100);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx", 110);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.host", 126);
|
||||
NR_reg_set_uchar((char *)"ice.pref.type.relayed", 0);
|
||||
|
||||
if (set_interface_priorities) {
|
||||
NR_reg_set_uchar((char *)"ice.pref.interface.rl0", 255);
|
||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "logging.h"
|
||||
#include "nsError.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
|
||||
// nICEr includes
|
||||
extern "C" {
|
||||
|
@ -72,6 +73,52 @@ namespace mozilla {
|
|||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
// Make an NrIceCandidate from the candidate |cand|.
|
||||
// This is not a member fxn because we want to hide the
|
||||
// defn of nr_ice_candidate but we pass by reference.
|
||||
static NrIceCandidate* MakeNrIceCandidate(const nr_ice_candidate& candc) {
|
||||
ScopedDeletePtr<NrIceCandidate> out(new NrIceCandidate());
|
||||
|
||||
int r;
|
||||
// Const-cast because the internal nICEr code isn't const-correct.
|
||||
nr_ice_candidate *cand = const_cast<nr_ice_candidate *>(&candc);
|
||||
char addr[INET6_ADDRSTRLEN + 1];
|
||||
|
||||
r = nr_transport_addr_get_addrstring(&cand->addr, addr, sizeof(addr));
|
||||
if (r)
|
||||
return nullptr;
|
||||
|
||||
int port;
|
||||
r=nr_transport_addr_get_port(&cand->addr, &port);
|
||||
if (r)
|
||||
return nullptr;
|
||||
|
||||
NrIceCandidate::Type type;
|
||||
|
||||
switch(cand->type) {
|
||||
case HOST:
|
||||
type = NrIceCandidate::ICE_HOST;
|
||||
break;
|
||||
case SERVER_REFLEXIVE:
|
||||
type = NrIceCandidate::ICE_SERVER_REFLEXIVE;
|
||||
break;
|
||||
case PEER_REFLEXIVE:
|
||||
type = NrIceCandidate::ICE_PEER_REFLEXIVE;
|
||||
break;
|
||||
case RELAYED:
|
||||
type = NrIceCandidate::ICE_RELAYED;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
out->host = addr;
|
||||
out->port = port;
|
||||
out->type = type;
|
||||
|
||||
return out.forget();
|
||||
}
|
||||
|
||||
// NrIceMediaStream
|
||||
RefPtr<NrIceMediaStream>
|
||||
NrIceMediaStream::Create(NrIceCtx *ctx,
|
||||
|
@ -150,6 +197,38 @@ nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::GetActivePair(int component,
|
||||
NrIceCandidate **localp,
|
||||
NrIceCandidate **remotep) {
|
||||
int r;
|
||||
nr_ice_candidate *local_int;
|
||||
nr_ice_candidate *remote_int;
|
||||
|
||||
r = nr_ice_media_stream_get_active(ctx_->peer(),
|
||||
stream_,
|
||||
component,
|
||||
&local_int, &remote_int);
|
||||
if (r)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ScopedDeletePtr<NrIceCandidate> local(
|
||||
MakeNrIceCandidate(*local_int));
|
||||
if (!local)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ScopedDeletePtr<NrIceCandidate> remote(
|
||||
MakeNrIceCandidate(*remote_int));
|
||||
if (!remote)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (localp)
|
||||
*localp = local.forget();
|
||||
if (remotep)
|
||||
*remotep = remote.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void NrIceMediaStream::EmitAllCandidates() {
|
||||
char **attrs = 0;
|
||||
|
@ -248,9 +327,16 @@ nsresult NrIceMediaStream::SendPacket(int component_id,
|
|||
|
||||
|
||||
void NrIceMediaStream::Ready() {
|
||||
MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'");
|
||||
state_ = ICE_OPEN;
|
||||
SignalReady(this);
|
||||
// This function is called whenever a stream becomes ready, but it
|
||||
// gets fired multiple times when a stream gets nominated repeatedly.
|
||||
if (state_ != ICE_OPEN) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'");
|
||||
state_ = ICE_OPEN;
|
||||
SignalReady(this);
|
||||
}
|
||||
else {
|
||||
MOZ_MTLOG(ML_DEBUG, "Stream ready callback fired again for '" << name_ << "'");
|
||||
}
|
||||
}
|
||||
|
||||
void NrIceMediaStream::Close() {
|
||||
|
|
|
@ -63,6 +63,21 @@ typedef struct nr_ice_media_stream_ nr_ice_media_stream;
|
|||
|
||||
class NrIceCtx;
|
||||
|
||||
/* A summary of a candidate, for use in asking which candidate
|
||||
pair is active */
|
||||
struct NrIceCandidate {
|
||||
enum Type {
|
||||
ICE_HOST,
|
||||
ICE_SERVER_REFLEXIVE,
|
||||
ICE_PEER_REFLEXIVE,
|
||||
ICE_RELAYED
|
||||
};
|
||||
|
||||
std::string host;
|
||||
uint16_t port;
|
||||
Type type;
|
||||
};
|
||||
|
||||
class NrIceMediaStream {
|
||||
public:
|
||||
static RefPtr<NrIceMediaStream> Create(NrIceCtx *ctx,
|
||||
|
@ -89,6 +104,14 @@ class NrIceMediaStream {
|
|||
// Parse trickle ICE candidate
|
||||
nsresult ParseTrickleCandidate(const std::string& candidate);
|
||||
|
||||
// Get the candidate pair currently active. It's the
|
||||
// caller's responsibility to free these.
|
||||
nsresult GetActivePair(int component,
|
||||
NrIceCandidate** local, NrIceCandidate** remote);
|
||||
|
||||
// The number of components
|
||||
int components() const { return components_; }
|
||||
|
||||
// The underlying nICEr stream
|
||||
nr_ice_media_stream *stream() { return stream_; }
|
||||
// Signals to indicate events. API users can (and should)
|
||||
|
@ -126,11 +149,7 @@ class NrIceMediaStream {
|
|||
ctx_(ctx),
|
||||
name_(name),
|
||||
components_(components),
|
||||
stream_(nullptr)
|
||||
{
|
||||
// XXX: components_ will be used eventually; placate clang in the meantime.
|
||||
(void)components_;
|
||||
}
|
||||
stream_(nullptr) {}
|
||||
|
||||
DISALLOW_COPY_ASSIGN(NrIceMediaStream);
|
||||
|
||||
|
|
|
@ -77,7 +77,9 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
fake_resolver_(),
|
||||
dns_resolver_(new NrIceResolver()),
|
||||
remote_(nullptr),
|
||||
candidate_filter_(nullptr) {
|
||||
candidate_filter_(nullptr),
|
||||
expected_local_type_(NrIceCandidate::ICE_HOST),
|
||||
expected_remote_type_(NrIceCandidate::ICE_HOST) {
|
||||
ice_ctx_->SignalGatheringCompleted.connect(this,
|
||||
&IceTestPeer::GatheringComplete);
|
||||
ice_ctx_->SignalCompleted.connect(this, &IceTestPeer::IceCompleted);
|
||||
|
@ -180,6 +182,11 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
return candidates;
|
||||
}
|
||||
|
||||
void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote) {
|
||||
expected_local_type_ = local;
|
||||
expected_remote_type_ = remote;
|
||||
}
|
||||
|
||||
bool gathering_complete() { return gathering_complete_; }
|
||||
int ready_ct() { return ready_ct_; }
|
||||
bool is_ready(size_t stream) {
|
||||
|
@ -255,6 +262,57 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
}
|
||||
|
||||
void DumpCandidate(std::string which, const NrIceCandidate& cand) {
|
||||
std::string type;
|
||||
|
||||
switch(cand.type) {
|
||||
case NrIceCandidate::ICE_HOST:
|
||||
type = "host";
|
||||
break;
|
||||
case NrIceCandidate::ICE_SERVER_REFLEXIVE:
|
||||
type = "srflx";
|
||||
break;
|
||||
case NrIceCandidate::ICE_PEER_REFLEXIVE:
|
||||
type = "prflx";
|
||||
break;
|
||||
case NrIceCandidate::ICE_RELAYED:
|
||||
type = "relay";
|
||||
break;
|
||||
default:
|
||||
FAIL();
|
||||
};
|
||||
|
||||
std::cerr << which
|
||||
<< " --> "
|
||||
<< type
|
||||
<< " "
|
||||
<< cand.host
|
||||
<< ":"
|
||||
<< cand.port
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void DumpAndCheckActiveCandidates() {
|
||||
std::cerr << "Active candidates:" << std::endl;
|
||||
for (size_t i=0; i < streams_.size(); ++i) {
|
||||
for (int j=0; j < streams_[i]->components(); ++j) {
|
||||
std::cerr << "Stream " << i << " component " << j+1 << std::endl;
|
||||
|
||||
NrIceCandidate *local;
|
||||
NrIceCandidate *remote;
|
||||
|
||||
nsresult res = streams_[i]->GetActivePair(j+1, &local, &remote);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
DumpCandidate("Local ", *local);
|
||||
ASSERT_EQ(expected_local_type_, local->type);
|
||||
DumpCandidate("Remote ", *remote);
|
||||
ASSERT_EQ(expected_remote_type_, remote->type);
|
||||
delete local;
|
||||
delete remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Close() {
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx),
|
||||
|
@ -286,8 +344,8 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void StreamReady(NrIceMediaStream *stream) {
|
||||
std::cerr << "Stream ready " << stream->name() << std::endl;
|
||||
++ready_ct_;
|
||||
std::cerr << "Stream ready " << stream->name() << " ct=" << ready_ct_ << std::endl;
|
||||
}
|
||||
|
||||
void IceCompleted(NrIceCtx *ctx) {
|
||||
|
@ -335,6 +393,8 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
nsRefPtr<NrIceResolver> dns_resolver_;
|
||||
IceTestPeer *remote_;
|
||||
CandidateFilter candidate_filter_;
|
||||
NrIceCandidate::Type expected_local_type_;
|
||||
NrIceCandidate::Type expected_remote_type_;
|
||||
};
|
||||
|
||||
class IceGatherTest : public ::testing::Test {
|
||||
|
@ -401,9 +461,11 @@ class IceConnectTest : public ::testing::Test {
|
|||
p2_->SetTurnServer(addr, port, username, password);
|
||||
}
|
||||
|
||||
void SetCandidateFilter(CandidateFilter filter) {
|
||||
void SetCandidateFilter(CandidateFilter filter, bool both=true) {
|
||||
p1_->SetCandidateFilter(filter);
|
||||
p2_->SetCandidateFilter(filter);
|
||||
if (both) {
|
||||
p2_->SetCandidateFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
void Connect() {
|
||||
|
@ -412,8 +474,21 @@ class IceConnectTest : public ::testing::Test {
|
|||
|
||||
ASSERT_TRUE_WAIT(p1_->ready_ct() == 1 && p2_->ready_ct() == 1, 5000);
|
||||
ASSERT_TRUE_WAIT(p1_->ice_complete() && p2_->ice_complete(), 5000);
|
||||
|
||||
p1_->DumpAndCheckActiveCandidates();
|
||||
p2_->DumpAndCheckActiveCandidates();
|
||||
}
|
||||
|
||||
void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote) {
|
||||
p1_->SetExpectedTypes(local, remote);
|
||||
p2_->SetExpectedTypes(local, remote);
|
||||
}
|
||||
|
||||
void SetExpectedTypes(NrIceCandidate::Type local1, NrIceCandidate::Type remote1,
|
||||
NrIceCandidate::Type local2, NrIceCandidate::Type remote2) {
|
||||
p1_->SetExpectedTypes(local1, remote1);
|
||||
p2_->SetExpectedTypes(local2, remote2);
|
||||
}
|
||||
|
||||
void ConnectP1(TrickleMode mode = TRICKLE_NONE) {
|
||||
p1_->Connect(p2_, mode);
|
||||
|
@ -700,6 +775,8 @@ TEST_F(IceConnectTest, TestConnectTurnOnly) {
|
|||
g_turn_user, g_turn_password);
|
||||
ASSERT_TRUE(Gather(true));
|
||||
SetCandidateFilter(IsRelayCandidate);
|
||||
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
|
||||
NrIceCandidate::Type::ICE_RELAYED);
|
||||
Connect();
|
||||
}
|
||||
|
||||
|
@ -712,6 +789,8 @@ TEST_F(IceConnectTest, TestSendReceiveTurnOnly) {
|
|||
g_turn_user, g_turn_password);
|
||||
ASSERT_TRUE(Gather(true));
|
||||
SetCandidateFilter(IsRelayCandidate);
|
||||
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
|
||||
NrIceCandidate::Type::ICE_RELAYED);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
|
|
@ -315,6 +315,10 @@ TEST_F(TurnClient, SendToSelf) {
|
|||
Allocate();
|
||||
SendTo(relay_addr_);
|
||||
ASSERT_TRUE_WAIT(received() == 100, 1000);
|
||||
PR_Sleep(10000); // Wait 10 seconds to make sure the
|
||||
// CreatePermission has time to complete/fail.
|
||||
SendTo(relay_addr_);
|
||||
ASSERT_TRUE_WAIT(received() == 200, 1000);
|
||||
}
|
||||
|
||||
TEST_F(TurnClient, AllocateDummyServer) {
|
||||
|
|
|
@ -799,10 +799,13 @@ int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pa
|
|||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling all pairs but %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,pair);
|
||||
|
||||
/* OK, we need to cancel off everything on this component */
|
||||
/* Cancel checks in WAITING and FROZEN per ICE S 8.1.2 */
|
||||
p2=TAILQ_FIRST(&comp->stream->check_list);
|
||||
while(p2){
|
||||
if((p2 != pair) && (p2->remote->component->component_id == comp->component_id)){
|
||||
if((p2 != pair) &&
|
||||
(p2->remote->component->component_id == comp->component_id) &&
|
||||
((p2->state == NR_ICE_PAIR_STATE_FROZEN) ||
|
||||
(p2->state == NR_ICE_PAIR_STATE_WAITING))) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling pair %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->as_string,p2);
|
||||
|
||||
if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2))
|
||||
|
|
|
@ -295,7 +295,6 @@ int nr_ice_media_stream_service_pre_answer_requests(nr_ice_peer_ctx *pctx, nr_ic
|
|||
nr_ice_component *pcomp;
|
||||
int r,_status;
|
||||
char *user = 0;
|
||||
char *lufrag, *rufrag;
|
||||
|
||||
if (serviced)
|
||||
*serviced = 0;
|
||||
|
@ -698,7 +697,6 @@ int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr
|
|||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len)
|
||||
{
|
||||
int r,_status;
|
||||
|
@ -710,7 +708,7 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in
|
|||
|
||||
/* Do we have an active pair yet? We should... */
|
||||
if(!comp->active)
|
||||
ABORT(R_BAD_ARGS);
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
/* OK, write to that pair, which means:
|
||||
1. Use the socket on our local side.
|
||||
|
@ -718,7 +716,7 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in
|
|||
*/
|
||||
comp->keepalive_needed=0; /* Suppress keepalives */
|
||||
if(r=nr_socket_sendto(comp->active->local->osock,data,len,0,
|
||||
&comp->active->remote->addr))
|
||||
&comp->active->remote->addr))
|
||||
ABORT(r);
|
||||
|
||||
_status=0;
|
||||
|
@ -726,6 +724,25 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_component *comp;
|
||||
|
||||
/* First find the peer component */
|
||||
if(r=nr_ice_peer_ctx_find_component(pctx, str, component, &comp))
|
||||
ABORT(r);
|
||||
|
||||
if(!comp->active)
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
if (local) *local = comp->active->local;
|
||||
if (remote) *remote = comp->active->remote;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote)
|
||||
{
|
||||
|
|
|
@ -88,7 +88,8 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c
|
|||
int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component);
|
||||
int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
|
||||
int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp);
|
||||
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx,nr_ice_media_stream *str, int component, UCHAR *data, int len);
|
||||
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len);
|
||||
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote);
|
||||
int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr_ice_component **compp);
|
||||
int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote);
|
||||
int
|
||||
|
|
|
@ -89,7 +89,7 @@ nr_stun_receive_message(nr_stun_message *req, nr_stun_message *msg)
|
|||
}
|
||||
|
||||
if (NR_STUN_GET_TYPE_METHOD(req->header.type) != NR_STUN_GET_TYPE_METHOD(msg->header.type)) {
|
||||
r_log(NR_LOG_STUN,LOG_NOTICE,"Inconsistent message method: %03x", msg->header.type);
|
||||
r_log(NR_LOG_STUN,LOG_NOTICE,"Inconsistent message method: %03x expected %03x", msg->header.type, req->header.type);
|
||||
ABORT(R_REJECTED);
|
||||
}
|
||||
|
||||
|
|
|
@ -176,6 +176,11 @@ static int nr_turn_stun_set_auth_params(nr_turn_stun_ctx *ctx,
|
|||
if (!ctx->nonce)
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
RFREE(ctx->stun->realm);
|
||||
ctx->stun->realm = r_strdup(ctx->realm);
|
||||
if (!ctx->stun->realm)
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
ctx->stun->auth_params.realm = ctx->realm;
|
||||
ctx->stun->auth_params.nonce = ctx->nonce;
|
||||
ctx->stun->auth_params.authenticate = 1; /* May already be 1 */
|
||||
|
|
|
@ -1051,10 +1051,14 @@ nsSocketTransportService::DiscoverMaxCount()
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Used to return connection info to Dashboard.cpp
|
||||
void
|
||||
nsSocketTransportService::AnalyzeConnection(nsTArray<SocketInfo> *data,
|
||||
struct SocketContext *context, bool aActive)
|
||||
{
|
||||
if (context->mHandler->mIsPrivate)
|
||||
return;
|
||||
PRFileDesc *aFD = context->mFD;
|
||||
bool tcp = (PR_GetDescType(aFD) == PR_DESC_SOCKET_TCP);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsNetAddr.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/VisualEventTracer.h"
|
||||
|
@ -433,6 +434,13 @@ nsDNSService::Init()
|
|||
// If a manual proxy is in use, disable prefetch implicitly
|
||||
prefs->AddObserver("network.proxy.type", this, false);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
observerService->AddObserver(this, "last-pb-context-exited", false);
|
||||
}
|
||||
}
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
|
@ -782,7 +790,8 @@ NS_IMETHODIMP
|
|||
nsDNSService::Observe(nsISupports *subject, const char *topic, const PRUnichar *data)
|
||||
{
|
||||
// we are only getting called if a preference has changed.
|
||||
NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0,
|
||||
NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0 ||
|
||||
strcmp(topic, "last-pb-context-exited") == 0,
|
||||
"unexpected observe call");
|
||||
|
||||
//
|
||||
|
|
|
@ -3343,6 +3343,9 @@ nsHttpConnectionMgr::ReadConnectionEntry(const nsACString &key,
|
|||
nsAutoPtr<nsConnectionEntry> &ent,
|
||||
void *aArg)
|
||||
{
|
||||
if (ent->mConnInfo->GetPrivate())
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
nsTArray<HttpRetParams> *args = static_cast<nsTArray<HttpRetParams> *> (aArg);
|
||||
HttpRetParams data;
|
||||
data.host = ent->mConnInfo->Host();
|
||||
|
|
|
@ -952,6 +952,7 @@ WebSocketChannel::WebSocketChannel() :
|
|||
mCompressor(nullptr),
|
||||
mDynamicOutputSize(0),
|
||||
mDynamicOutput(nullptr),
|
||||
mPrivateBrowsing(false),
|
||||
mConnectionLogService(nullptr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||
|
@ -1328,7 +1329,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
|||
|
||||
NS_DispatchToMainThread(new CallOnMessageAvailable(this, utf8Data, -1));
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
if (mConnectionLogService && !mPrivateBrowsing) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1419,7 +1420,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
|||
payloadLength));
|
||||
// To add the header to 'Networking Dashboard' log
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
if (mConnectionLogService && !mPrivateBrowsing) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1844,7 +1845,7 @@ WebSocketChannel::CleanupConnection()
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
if (mConnectionLogService && !mPrivateBrowsing) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
|
@ -2678,7 +2679,9 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (mConnectionLogService) {
|
||||
mPrivateBrowsing = NS_UsePrivateBrowsing(localChannel);
|
||||
|
||||
if (mConnectionLogService && !mPrivateBrowsing) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -2783,7 +2786,7 @@ WebSocketChannel::SendMsgCommon(const nsACString *aMsg, bool aIsBinary,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
if (mConnectionLogService && !mPrivateBrowsing) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
|
|
@ -247,6 +247,7 @@ private:
|
|||
nsWSCompression *mCompressor;
|
||||
uint32_t mDynamicOutputSize;
|
||||
uint8_t *mDynamicOutput;
|
||||
bool mPrivateBrowsing;
|
||||
|
||||
nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
|
||||
uint32_t mSerial;
|
||||
|
|
|
@ -332,7 +332,6 @@
|
|||
"content/base/test/test_bug166235.html":"clipboard undefined",
|
||||
|
||||
"dom/tests/mochitest/general/test_idleapi_permissions.html":"",
|
||||
"dom/tests/mochitest/general/test_interfaces.html":"",
|
||||
"dom/tests/mochitest/general/test_paste_selection.html":"No clipboard",
|
||||
|
||||
"dom/tests/mochitest/geolocation/test_allowCurrent.html":"Bug 910235 - Error: no message manager set when calling method: [nsIObserver::observe]",
|
||||
|
|
Загрузка…
Ссылка в новой задаче