mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
9d8390c149
@ -99,6 +99,7 @@ var AccessFu = {
|
||||
Services.obs.addObserver(this, 'Accessibility:NextObject', false);
|
||||
Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
|
||||
Services.obs.addObserver(this, 'Accessibility:CurrentObject', false);
|
||||
this.chromeWin.addEventListener('TabOpen', this);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -118,6 +119,8 @@ var AccessFu = {
|
||||
|
||||
Input.detach();
|
||||
|
||||
this.chromeWin.removeEventListener('TabOpen', this);
|
||||
|
||||
Services.obs.removeObserver(this, 'remote-browser-frame-shown');
|
||||
Services.obs.removeObserver(this, 'Accessibility:NextObject');
|
||||
Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
|
||||
@ -205,10 +208,20 @@ var AccessFu = {
|
||||
},
|
||||
|
||||
handleEvent: function handleEvent(aEvent) {
|
||||
if (aEvent.type == 'mozContentEvent' &&
|
||||
aEvent.detail.type == 'accessibility-screenreader') {
|
||||
this._systemPref = aEvent.detail.enabled;
|
||||
this._enableOrDisable();
|
||||
switch (aEvent.type) {
|
||||
case 'mozContentEvent':
|
||||
{
|
||||
if (aEvent.detail.type == 'accessibility-screenreader') {
|
||||
this._systemPref = aEvent.detail.enabled;
|
||||
this._enableOrDisable();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'TabOpen':
|
||||
{
|
||||
this._loadFrameScript(Utils.getMessageManager(aEvent.target));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -47,7 +47,7 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
|
||||
// nsISupports methods
|
||||
//-----------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode);
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode)
|
||||
|
||||
//-----------------------------------------------------
|
||||
// nsIWinAccessNode methods
|
||||
@ -92,7 +92,7 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
|
||||
// A use case for this is for screen readers that need to switch context or
|
||||
// 'virtual buffer' when focus moves from one browser tab area to another.
|
||||
static const GUID SID_IAccessibleContentDocument =
|
||||
{ 0xa5d8e1f3,0x3571,0x4d8f,0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e };
|
||||
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
|
||||
if (guidService == SID_IAccessibleContentDocument) {
|
||||
if (iid != IID_IAccessible)
|
||||
return E_NOINTERFACE;
|
||||
@ -153,7 +153,7 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
|
||||
*/
|
||||
|
||||
static const GUID IID_SimpleDOMDeprecated =
|
||||
{ 0x0c539790,0x12e4,0x11cf,0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8 };
|
||||
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
|
||||
if (guidService == IID_ISimpleDOMNode ||
|
||||
guidService == IID_SimpleDOMDeprecated ||
|
||||
guidService == IID_IAccessible || guidService == IID_IAccessible2)
|
||||
|
@ -66,6 +66,10 @@ function closePaymentFlowDialog(aCallback) {
|
||||
|
||||
content.removeEventListener("mozContentEvent",
|
||||
closePaymentFlowReturn);
|
||||
|
||||
let glue = Cc["@mozilla.org/payment/ui-glue;1"]
|
||||
.createInstance(Ci.nsIPaymentUIGlue);
|
||||
glue.cleanup();
|
||||
});
|
||||
|
||||
browser.shell.sendChromeEvent(detail);
|
||||
|
@ -33,10 +33,16 @@ PaymentUI.prototype = {
|
||||
confirmPaymentRequest: function confirmPaymentRequest(aRequests,
|
||||
aSuccessCb,
|
||||
aErrorCb) {
|
||||
let _error = function _error(errorMsg) {
|
||||
if (aErrorCb) {
|
||||
aErrorCb.onresult(errorMsg);
|
||||
}
|
||||
};
|
||||
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let content = browser.getContentWindow();
|
||||
if (!content && aErrorCb) {
|
||||
aErrorCb.onresult("NO_CONTENT_WINDOW");
|
||||
if (!content) {
|
||||
_error("NO_CONTENT_WINDOW");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -56,15 +62,13 @@ PaymentUI.prototype = {
|
||||
content.addEventListener("mozContentEvent", function handleSelection(evt) {
|
||||
let msg = evt.detail;
|
||||
if (msg.id != id) {
|
||||
debug("mozContentEvent. evt.detail.id != " + id);
|
||||
content.removeEventListener("mozContentEvent", handleSelection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.userSelection && aSuccessCb) {
|
||||
aSuccessCb.onresult(msg.userSelection);
|
||||
} else if (msg.errorMsg && aErrorCb) {
|
||||
aErrorCb.onresult(msg.errorMsg);
|
||||
} else if (msg.errorMsg) {
|
||||
_error(msg.errorMsg);
|
||||
}
|
||||
|
||||
content.removeEventListener("mozContentEvent", handleSelection);
|
||||
@ -75,11 +79,18 @@ PaymentUI.prototype = {
|
||||
|
||||
showPaymentFlow: function showPaymentFlow(aPaymentFlowInfo, aErrorCb) {
|
||||
debug("showPaymentFlow. uri " + aPaymentFlowInfo.uri);
|
||||
|
||||
let _error = function _error(errorMsg) {
|
||||
if (aErrorCb) {
|
||||
aErrorCb.onresult(errorMsg);
|
||||
}
|
||||
};
|
||||
|
||||
// We ask the UI to browse to the selected payment flow.
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let content = browser.getContentWindow();
|
||||
if (!content && aErrorCb) {
|
||||
aErrorCb.onresult("NO_CONTENT_WINDOW");
|
||||
if (!content) {
|
||||
_error("NO_CONTENT_WINDOW");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -95,14 +106,18 @@ PaymentUI.prototype = {
|
||||
// At some point the UI would send the created iframe back so the
|
||||
// callbacks for firing DOMRequest events can be loaded on its
|
||||
// content.
|
||||
content.addEventListener("mozContentEvent", function loadPaymentShim(evt) {
|
||||
if (evt.detail.id != id || !evt.detail.frame) {
|
||||
content.addEventListener("mozContentEvent", (function loadPaymentShim(evt) {
|
||||
if (evt.detail.id != id) {
|
||||
content.removeEventListener("mozContentEvent", loadPaymentShim);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to load the payment shim file containing the payment callbacks
|
||||
// in the content script.
|
||||
if (!evt.detail.frame && !evt.detail.errorMsg) {
|
||||
_error("ERROR_LOADING_PAYMENT_SHIM");
|
||||
return;
|
||||
}
|
||||
let frame = evt.detail.frame;
|
||||
let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner)
|
||||
.frameLoader;
|
||||
@ -111,17 +126,40 @@ PaymentUI.prototype = {
|
||||
mm.loadFrameScript(kPaymentShimFile, true);
|
||||
} catch (e) {
|
||||
debug("Error loading " + kPaymentShimFile + " as a frame script: " + e);
|
||||
if (aErrorCb) {
|
||||
aErrorCb.onresult("ERROR_LOADING_PAYMENT_SHIM");
|
||||
}
|
||||
_error("ERROR_LOADING_PAYMENT_SHIM");
|
||||
} finally {
|
||||
content.removeEventListener("mozContentEvent", loadPaymentShim);
|
||||
}
|
||||
});
|
||||
}).bind(this));
|
||||
|
||||
// We also listen for UI notifications about a closed payment flow. The UI
|
||||
// should provide the reason of the closure within the 'errorMsg' parameter
|
||||
this._notifyPayFlowClosed = function _notifyPayFlowClosed (evt) {
|
||||
if (evt.detail.id != id) {
|
||||
return;
|
||||
}
|
||||
if (evt.detail.errorMsg) {
|
||||
_error(evt.detail.errorMsg);
|
||||
content.removeEventListener("mozContentEvent",
|
||||
this._notifyPayFlowClosed);
|
||||
return;
|
||||
}
|
||||
};
|
||||
content.addEventListener("mozContentEvent",
|
||||
this._notifyPayFlowClosed.bind(this));
|
||||
|
||||
browser.shell.sendChromeEvent(detail);
|
||||
},
|
||||
|
||||
cleanup: function cleanup() {
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let content = browser.getContentWindow();
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
content.removeEventListener("mozContentEvent", this._notifyPayFlowClosed);
|
||||
},
|
||||
|
||||
getRandomId: function getRandomId() {
|
||||
return uuidgen.generateUUID().toString();
|
||||
},
|
||||
|
@ -1172,10 +1172,10 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
pref("image.mem.max_decoded_image_kb", 256000);
|
||||
|
||||
// Example social provider
|
||||
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
|
||||
pref("social.manifest.facebook", "{\"origin\":\"https://www.facebook.com\",\"name\":\"Facebook Messenger\",\"workerURL\":\"https://www.facebook.com/desktop/fbdesktop2/socialfox/fbworker.js.php\",\"iconURL\":\"data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAAX0lEQVQ4jWP4%2F%2F8%2FAyUYTFhHzjgDxP9JxGeQDSBVMxgTbUBCxer%2Fr999%2BQ8DJBuArJksA9A10s8AXIBoA0B%2BR%2FY%2FjD%2BEwoBoA1yT5v3PbdmCE8MAshhID%2FUMoDgzUYIBj0Cgi7ar4coAAAAASUVORK5CYII%3D\",\"sidebarURL\":\"https://www.facebook.com/desktop/fbdesktop2/?socialfox=true\"}");
|
||||
// Comma-separated list of nsIURI::prePaths that are allowed to activate
|
||||
// built-in social functionality.
|
||||
pref("social.activation.whitelist", "https://motown-dev.mozillalabs.com");
|
||||
pref("social.activation.whitelist", "https://www.facebook.com");
|
||||
pref("social.sidebar.open", true);
|
||||
pref("social.active", false);
|
||||
pref("social.toast-notifications.enabled", true);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.7 KiB |
@ -331,6 +331,7 @@ Function .onUserAbort
|
||||
${NSD_KillTimer} StartInstall
|
||||
${NSD_KillTimer} CheckInstall
|
||||
${NSD_KillTimer} FinishInstall
|
||||
${NSD_KillTimer} DisplayDownloadError
|
||||
|
||||
Delete "$PLUGINSDIR\download.exe"
|
||||
Delete "$PLUGINSDIR\${CONFIG_INI}"
|
||||
@ -927,12 +928,8 @@ Function OnDownload
|
||||
|
||||
${If} $0 == 0
|
||||
${OrIf} $1 == 0
|
||||
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK 0
|
||||
ExecShell "open" "${URLManualDownload}"
|
||||
; The following will exit the installer
|
||||
SetAutoClose true
|
||||
StrCpy $R9 2
|
||||
Call RelativeGotoPage
|
||||
; Use a timer so the UI has a chance to update
|
||||
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
|
||||
Return
|
||||
${EndIf}
|
||||
|
||||
@ -1020,12 +1017,8 @@ Function CheckInstall
|
||||
${NSD_KillTimer} CheckInstall
|
||||
; Close the handle that prevents modification of the full installer
|
||||
System::Call 'kernel32::CloseHandle(i $HandleDownload)'
|
||||
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK 0
|
||||
ExecShell "open" "${URLManualDownload}"
|
||||
; The following will exit the installer
|
||||
SetAutoClose true
|
||||
StrCpy $R9 2
|
||||
Call RelativeGotoPage
|
||||
; Use a timer so the UI has a chance to update
|
||||
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
|
||||
Return
|
||||
${EndIf}
|
||||
|
||||
@ -1336,5 +1329,32 @@ Function LaunchAppFromElevatedProcess
|
||||
Exec "$\"$0$\""
|
||||
FunctionEnd
|
||||
|
||||
Function DisplayDownloadError
|
||||
${NSD_KillTimer} DisplayDownloadError
|
||||
StrCpy $R9 "false"
|
||||
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK 0
|
||||
StrCpy $R9 "true"
|
||||
|
||||
${If} "$R9" == "true"
|
||||
ClearErrors
|
||||
${GetParameters} $0
|
||||
${GetOptions} "$0" "/UAC:" $1
|
||||
${If} ${Errors}
|
||||
Call OpenManualDownloadURL
|
||||
${Else}
|
||||
GetFunctionAddress $0 OpenManualDownloadURL
|
||||
UAC::ExecCodeSegment $0
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
SetAutoClose true
|
||||
StrCpy $R9 2
|
||||
Call RelativeGotoPage
|
||||
FunctionEnd
|
||||
|
||||
Function OpenManualDownloadURL
|
||||
ExecShell "open" "${URLManualDownload}"
|
||||
FunctionEnd
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
|
@ -393,7 +393,7 @@ public class FennecNativeDriver implements Driver {
|
||||
|
||||
String[] lines = data.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String[] parts = lines[i].split("=");
|
||||
String[] parts = lines[i].split("=", 2);
|
||||
retVal.put(parts[0].trim(), parts[1].trim());
|
||||
}
|
||||
return retVal;
|
||||
|
@ -200,14 +200,6 @@ public:
|
||||
*/
|
||||
static JSContext* GetContextFromDocument(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* When a document's scope changes (e.g., from document.open(), call this
|
||||
* function to move all content wrappers from the old scope to the new one.
|
||||
*/
|
||||
static nsresult ReparentContentWrappersInScope(JSContext *cx,
|
||||
nsIScriptGlobalObject *aOldScope,
|
||||
nsIScriptGlobalObject *aNewScope);
|
||||
|
||||
static bool IsCallerChrome();
|
||||
|
||||
static bool IsCallerTrustedForRead();
|
||||
|
@ -1721,23 +1721,6 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentUtils::ReparentContentWrappersInScope(JSContext *cx,
|
||||
nsIScriptGlobalObject *aOldScope,
|
||||
nsIScriptGlobalObject *aNewScope)
|
||||
{
|
||||
JSObject *oldScopeObj = aOldScope->GetGlobalJSObject();
|
||||
JSObject *newScopeObj = aNewScope->GetGlobalJSObject();
|
||||
|
||||
if (!newScopeObj || !oldScopeObj) {
|
||||
// We can't really do anything without the JSObjects.
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return sXPConnect->MoveWrappers(cx, oldScopeObj, newScopeObj);
|
||||
}
|
||||
|
||||
nsPIDOMWindow *
|
||||
nsContentUtils::GetWindowFromCaller()
|
||||
{
|
||||
|
@ -1041,7 +1041,15 @@ public:
|
||||
const float* data);
|
||||
|
||||
void UseProgram(WebGLProgram *prog);
|
||||
bool ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength);
|
||||
bool ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object,
|
||||
GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength);
|
||||
bool ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
|
||||
GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
|
||||
WebGLboolean aTranspose);
|
||||
bool ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location);
|
||||
void ValidateProgram(WebGLProgram *prog);
|
||||
bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object);
|
||||
|
||||
void VertexAttrib1f(WebGLuint index, WebGLfloat x0);
|
||||
void VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1);
|
||||
|
@ -3610,170 +3610,249 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define OBTAIN_UNIFORM_LOCATION(info) \
|
||||
if (!ValidateObjectAllowNull(info, location_object)) \
|
||||
return; \
|
||||
if (!location_object) \
|
||||
return; \
|
||||
/* the need to check specifically for !mCurrentProgram here is explained in bug 657556 */ \
|
||||
if (!mCurrentProgram) \
|
||||
return ErrorInvalidOperation("%s: no program is currently bound", info); \
|
||||
if (mCurrentProgram != location_object->Program()) \
|
||||
return ErrorInvalidOperation("%s: this uniform location doesn't correspond to the current program", info); \
|
||||
if (mCurrentProgram->Generation() != location_object->ProgramGeneration()) \
|
||||
return ErrorInvalidOperation("%s: This uniform location is obsolete since the program has been relinked", info); \
|
||||
GLint location = location_object->Location();
|
||||
|
||||
#define SIMPLE_ARRAY_METHOD_UNIFORM(name, expectedElemSize, arrayType, ptrType) \
|
||||
void \
|
||||
WebGLContext::name##_base(WebGLUniformLocation *location_object, \
|
||||
uint32_t arrayLength, const ptrType* data) { \
|
||||
if (!IsContextStable()) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
int uniformElemSize = location_object->ElementSize(); \
|
||||
if (expectedElemSize != uniformElemSize) { \
|
||||
return ErrorInvalidOperation( \
|
||||
#name ": this function expected a uniform of element size %d," \
|
||||
" got a uniform of element size %d", \
|
||||
expectedElemSize, \
|
||||
uniformElemSize); \
|
||||
} \
|
||||
const WebGLUniformInfo& info = location_object->Info(); \
|
||||
if (arrayLength == 0 || \
|
||||
arrayLength % expectedElemSize) \
|
||||
{ \
|
||||
return ErrorInvalidValue("%s: expected an array of length a multiple" \
|
||||
" of %d, got an array of length %d", \
|
||||
#name, \
|
||||
expectedElemSize, \
|
||||
arrayLength); \
|
||||
} \
|
||||
if (!info.isArray && \
|
||||
arrayLength != expectedElemSize) { \
|
||||
return ErrorInvalidOperation("%s: expected an array of length exactly" \
|
||||
" %d (since this uniform is not an array" \
|
||||
" uniform), got an array of length %d", \
|
||||
#name, \
|
||||
expectedElemSize, \
|
||||
arrayLength); \
|
||||
} \
|
||||
\
|
||||
uint32_t numElementsToUpload = \
|
||||
NS_MIN(info.arraySize, arrayLength / expectedElemSize); \
|
||||
MakeContextCurrent(); \
|
||||
gl->f##name(location, numElementsToUpload, data); \
|
||||
void
|
||||
WebGLContext::Uniform1i(WebGLUniformLocation *location_object, WebGLint a1)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform1i", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1i(location, a1);
|
||||
}
|
||||
|
||||
#define SIMPLE_MATRIX_METHOD_UNIFORM(name, dim) \
|
||||
void \
|
||||
WebGLContext::name##_base(WebGLUniformLocation* location_object, \
|
||||
WebGLboolean aTranspose, uint32_t arrayLength, \
|
||||
const float* data) \
|
||||
{ \
|
||||
uint32_t expectedElemSize = (dim)*(dim); \
|
||||
if (!IsContextStable()) { \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
uint32_t uniformElemSize = location_object->ElementSize(); \
|
||||
if (expectedElemSize != uniformElemSize) { \
|
||||
return ErrorInvalidOperation( \
|
||||
#name ": this function expected a uniform of element size %d," \
|
||||
" got a uniform of element size %d", \
|
||||
expectedElemSize, \
|
||||
uniformElemSize); \
|
||||
} \
|
||||
const WebGLUniformInfo& info = location_object->Info(); \
|
||||
if (arrayLength == 0 || \
|
||||
arrayLength % expectedElemSize) \
|
||||
{ \
|
||||
return ErrorInvalidValue("%s: expected an array of length a multiple" \
|
||||
" of %d, got an array of length %d", \
|
||||
#name, \
|
||||
expectedElemSize, \
|
||||
arrayLength); \
|
||||
} \
|
||||
if (!info.isArray && \
|
||||
arrayLength != expectedElemSize) { \
|
||||
return ErrorInvalidOperation("%s: expected an array of length exactly" \
|
||||
" %d (since this uniform is not an array" \
|
||||
" uniform), got an array of length %d", \
|
||||
#name, \
|
||||
expectedElemSize, \
|
||||
arrayLength); \
|
||||
} \
|
||||
if (aTranspose) { \
|
||||
return ErrorInvalidValue(#name ": transpose must be FALSE as per the " \
|
||||
"OpenGL ES 2.0 spec"); \
|
||||
} \
|
||||
\
|
||||
MakeContextCurrent(); \
|
||||
uint32_t numElementsToUpload = \
|
||||
NS_MIN(info.arraySize, arrayLength / (expectedElemSize)); \
|
||||
gl->f##name(location, numElementsToUpload, false, data); \
|
||||
void
|
||||
WebGLContext::Uniform2i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
WebGLint a2)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform2i", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2i(location, a1, a2);
|
||||
}
|
||||
|
||||
#define SIMPLE_METHOD_UNIFORM_1(glname, name, t1) \
|
||||
void WebGLContext::name(WebGLUniformLocation *location_object, t1 a1) { \
|
||||
if (!IsContextStable()) \
|
||||
return; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
MakeContextCurrent(); gl->f##glname(location, a1); \
|
||||
void
|
||||
WebGLContext::Uniform3i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
WebGLint a2, WebGLint a3)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform3i", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3i(location, a1, a2, a3);
|
||||
}
|
||||
|
||||
#define SIMPLE_METHOD_UNIFORM_2(glname, name, t1, t2) \
|
||||
void WebGLContext::name(WebGLUniformLocation *location_object, t1 a1, t2 a2) { \
|
||||
if (!IsContextStable()) \
|
||||
return; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
MakeContextCurrent(); gl->f##glname(location, a1, a2); \
|
||||
void
|
||||
WebGLContext::Uniform4i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
WebGLint a2, WebGLint a3, WebGLint a4)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform4i", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4i(location, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
#define SIMPLE_METHOD_UNIFORM_3(glname, name, t1, t2, t3) \
|
||||
void WebGLContext::name(WebGLUniformLocation *location_object, \
|
||||
t1 a1, t2 a2, t3 a3) { \
|
||||
if (!IsContextStable()) \
|
||||
return; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
MakeContextCurrent(); gl->f##glname(location, a1, a2, a3); \
|
||||
void
|
||||
WebGLContext::Uniform1f(WebGLUniformLocation *location_object, WebGLfloat a1)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform1f", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1f(location, a1);
|
||||
}
|
||||
|
||||
#define SIMPLE_METHOD_UNIFORM_4(glname, name, t1, t2, t3, t4) \
|
||||
void WebGLContext::name(WebGLUniformLocation *location_object, \
|
||||
t1 a1, t2 a2, t3 a3, t4 a4) { \
|
||||
if (!IsContextStable()) \
|
||||
return; \
|
||||
OBTAIN_UNIFORM_LOCATION(#name ": location") \
|
||||
MakeContextCurrent(); gl->f##glname(location, a1, a2, a3, a4); \
|
||||
void
|
||||
WebGLContext::Uniform2f(WebGLUniformLocation *location_object, WebGLfloat a1,
|
||||
WebGLfloat a2)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform2f", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2f(location, a1, a2);
|
||||
}
|
||||
|
||||
SIMPLE_METHOD_UNIFORM_1(Uniform1i, Uniform1i, WebGLint)
|
||||
SIMPLE_METHOD_UNIFORM_2(Uniform2i, Uniform2i, WebGLint, WebGLint)
|
||||
SIMPLE_METHOD_UNIFORM_3(Uniform3i, Uniform3i, WebGLint, WebGLint, WebGLint)
|
||||
SIMPLE_METHOD_UNIFORM_4(Uniform4i, Uniform4i, WebGLint, WebGLint, WebGLint, WebGLint)
|
||||
void
|
||||
WebGLContext::Uniform3f(WebGLUniformLocation *location_object, WebGLfloat a1,
|
||||
WebGLfloat a2, WebGLfloat a3)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform3f", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3f(location, a1, a2, a3);
|
||||
}
|
||||
|
||||
SIMPLE_METHOD_UNIFORM_1(Uniform1f, Uniform1f, WebGLfloat)
|
||||
SIMPLE_METHOD_UNIFORM_2(Uniform2f, Uniform2f, WebGLfloat, WebGLfloat)
|
||||
SIMPLE_METHOD_UNIFORM_3(Uniform3f, Uniform3f, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||
SIMPLE_METHOD_UNIFORM_4(Uniform4f, Uniform4f, WebGLfloat, WebGLfloat, WebGLfloat, WebGLfloat)
|
||||
void
|
||||
WebGLContext::Uniform4f(WebGLUniformLocation *location_object, WebGLfloat a1,
|
||||
WebGLfloat a2, WebGLfloat a3, WebGLfloat a4)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform4f", location_object, location))
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4f(location, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1iv, 1, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2iv, 2, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3iv, 3, Int32, WebGLint)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4iv, 4, Int32, WebGLint)
|
||||
void
|
||||
WebGLContext::Uniform1iv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLint* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform1iv", 1, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1iv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform1fv, 1, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform2fv, 2, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform3fv, 3, Float32, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_UNIFORM(Uniform4fv, 4, Float32, WebGLfloat)
|
||||
void
|
||||
WebGLContext::Uniform2iv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLint* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform2iv", 2, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2iv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
SIMPLE_MATRIX_METHOD_UNIFORM(UniformMatrix2fv, 2)
|
||||
SIMPLE_MATRIX_METHOD_UNIFORM(UniformMatrix3fv, 3)
|
||||
SIMPLE_MATRIX_METHOD_UNIFORM(UniformMatrix4fv, 4)
|
||||
void
|
||||
WebGLContext::Uniform3iv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLint* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform3iv", 3, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3iv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Uniform4iv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLint* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform4iv", 4, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4iv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Uniform1fv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLfloat* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform1fv", 1, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1fv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Uniform2fv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLfloat* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform2fv", 2, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2fv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Uniform3fv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLfloat* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform3fv", 3, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3fv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Uniform4fv_base(WebGLUniformLocation *location_object,
|
||||
uint32_t arrayLength, const WebGLfloat* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformArraySetter("Uniform4fv", 4, location_object, location,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4fv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::UniformMatrix2fv_base(WebGLUniformLocation* location_object,
|
||||
WebGLboolean aTranspose, uint32_t arrayLength,
|
||||
const float* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformMatrixArraySetter("UniformMatrix2fv", 2, location_object, location,
|
||||
numElementsToUpload, arrayLength, aTranspose)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniformMatrix2fv(location, numElementsToUpload, false, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::UniformMatrix3fv_base(WebGLUniformLocation* location_object,
|
||||
WebGLboolean aTranspose, uint32_t arrayLength,
|
||||
const float* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformMatrixArraySetter("UniformMatrix3fv", 3, location_object, location,
|
||||
numElementsToUpload, arrayLength, aTranspose)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniformMatrix3fv(location, numElementsToUpload, false, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::UniformMatrix4fv_base(WebGLUniformLocation* location_object,
|
||||
WebGLboolean aTranspose, uint32_t arrayLength,
|
||||
const float* data)
|
||||
{
|
||||
uint32_t numElementsToUpload;
|
||||
GLint location;
|
||||
if (!ValidateUniformMatrixArraySetter("UniformMatrix4fv", 4, location_object, location,
|
||||
numElementsToUpload, arrayLength, aTranspose)) {
|
||||
return;
|
||||
}
|
||||
MakeContextCurrent();
|
||||
gl->fUniformMatrix4fv(location, numElementsToUpload, false, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::VertexAttrib1f(WebGLuint index, WebGLfloat x0)
|
||||
@ -3856,36 +3935,86 @@ WebGLContext::VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
|
||||
}
|
||||
}
|
||||
|
||||
#define SIMPLE_ARRAY_METHOD_NO_COUNT(name, cnt, ptrType) \
|
||||
void \
|
||||
WebGLContext::name##_base(WebGLuint idx, uint32_t arrayLength, \
|
||||
const WebGLfloat* ptr) \
|
||||
{ \
|
||||
if (!IsContextStable()) { \
|
||||
return; \
|
||||
} \
|
||||
if (arrayLength < cnt) { \
|
||||
return ErrorInvalidOperation(#name ": array must be >= %d elements", \
|
||||
cnt); \
|
||||
} \
|
||||
\
|
||||
MakeContextCurrent(); \
|
||||
if (idx) { \
|
||||
gl->f##name(idx, ptr); \
|
||||
} else { \
|
||||
mVertexAttrib0Vector[0] = ptr[0]; \
|
||||
mVertexAttrib0Vector[1] = cnt > 1 ? ptr[1] : ptrType(0); \
|
||||
mVertexAttrib0Vector[2] = cnt > 2 ? ptr[2] : ptrType(0); \
|
||||
mVertexAttrib0Vector[3] = cnt > 3 ? ptr[3] : ptrType(1); \
|
||||
if (gl->IsGLES2()) \
|
||||
gl->f##name(idx, ptr); \
|
||||
} \
|
||||
|
||||
void
|
||||
WebGLContext::VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength,
|
||||
const WebGLfloat* ptr)
|
||||
{
|
||||
if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
if (idx) {
|
||||
gl->fVertexAttrib1fv(idx, ptr);
|
||||
} else {
|
||||
mVertexAttrib0Vector[0] = ptr[0];
|
||||
mVertexAttrib0Vector[1] = WebGLfloat(0);
|
||||
mVertexAttrib0Vector[2] = WebGLfloat(0);
|
||||
mVertexAttrib0Vector[3] = WebGLfloat(1);
|
||||
if (gl->IsGLES2())
|
||||
gl->fVertexAttrib1fv(idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib1fv, 1, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib2fv, 2, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib3fv, 3, WebGLfloat)
|
||||
SIMPLE_ARRAY_METHOD_NO_COUNT(VertexAttrib4fv, 4, WebGLfloat)
|
||||
void
|
||||
WebGLContext::VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength,
|
||||
const WebGLfloat* ptr)
|
||||
{
|
||||
if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
if (idx) {
|
||||
gl->fVertexAttrib2fv(idx, ptr);
|
||||
} else {
|
||||
mVertexAttrib0Vector[0] = ptr[0];
|
||||
mVertexAttrib0Vector[1] = ptr[1];
|
||||
mVertexAttrib0Vector[2] = WebGLfloat(0);
|
||||
mVertexAttrib0Vector[3] = WebGLfloat(1);
|
||||
if (gl->IsGLES2())
|
||||
gl->fVertexAttrib2fv(idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength,
|
||||
const WebGLfloat* ptr)
|
||||
{
|
||||
if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
if (idx) {
|
||||
gl->fVertexAttrib3fv(idx, ptr);
|
||||
} else {
|
||||
mVertexAttrib0Vector[0] = ptr[0];
|
||||
mVertexAttrib0Vector[1] = ptr[1];
|
||||
mVertexAttrib0Vector[2] = ptr[2];
|
||||
mVertexAttrib0Vector[3] = WebGLfloat(1);
|
||||
if (gl->IsGLES2())
|
||||
gl->fVertexAttrib3fv(idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength,
|
||||
const WebGLfloat* ptr)
|
||||
{
|
||||
if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
if (idx) {
|
||||
gl->fVertexAttrib4fv(idx, ptr);
|
||||
} else {
|
||||
mVertexAttrib0Vector[0] = ptr[0];
|
||||
mVertexAttrib0Vector[1] = ptr[1];
|
||||
mVertexAttrib0Vector[2] = ptr[2];
|
||||
mVertexAttrib0Vector[3] = ptr[3];
|
||||
if (gl->IsGLES2())
|
||||
gl->fVertexAttrib4fv(idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::UseProgram(WebGLProgram *prog)
|
||||
|
@ -657,6 +657,151 @@ bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, in
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object)
|
||||
{
|
||||
if (!ValidateObjectAllowNull(info, location_object))
|
||||
return false;
|
||||
if (!location_object)
|
||||
return false;
|
||||
/* the need to check specifically for !mCurrentProgram here is explained in bug 657556 */
|
||||
if (!mCurrentProgram) {
|
||||
ErrorInvalidOperation("%s: no program is currently bound", info);
|
||||
return false;
|
||||
}
|
||||
if (mCurrentProgram != location_object->Program()) {
|
||||
ErrorInvalidOperation("%s: this uniform location doesn't correspond to the current program", info);
|
||||
return false;
|
||||
}
|
||||
if (mCurrentProgram->Generation() != location_object->ProgramGeneration()) {
|
||||
ErrorInvalidOperation("%s: This uniform location is obsolete since the program has been relinked", info);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength)
|
||||
{
|
||||
if (!IsContextStable()) {
|
||||
return false;
|
||||
}
|
||||
if (arrayLength < cnt) {
|
||||
ErrorInvalidOperation("%s: array must be >= %d elements", name, cnt);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object,
|
||||
GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return false;
|
||||
nsCString nameString(name);
|
||||
nsCString suffix = NS_LITERAL_CSTRING(": location");
|
||||
nsCString concatenated = nameString + suffix;
|
||||
if (!ValidateUniformLocation(concatenated.get(), location_object))
|
||||
return false;
|
||||
location = location_object->Location();
|
||||
uint32_t uniformElemSize = location_object->ElementSize();
|
||||
if (expectedElemSize != uniformElemSize) {
|
||||
ErrorInvalidOperation("%s: this function expected a uniform of element size %d,"
|
||||
" got a uniform of element size %d", name,
|
||||
expectedElemSize,
|
||||
uniformElemSize);
|
||||
return false;
|
||||
}
|
||||
const WebGLUniformInfo& info = location_object->Info();
|
||||
if (arrayLength == 0 ||
|
||||
arrayLength % expectedElemSize)
|
||||
{
|
||||
ErrorInvalidValue("%s: expected an array of length a multiple"
|
||||
" of %d, got an array of length %d", name,
|
||||
expectedElemSize,
|
||||
arrayLength);
|
||||
return false;
|
||||
}
|
||||
if (!info.isArray &&
|
||||
arrayLength != expectedElemSize) {
|
||||
ErrorInvalidOperation("%s: expected an array of length exactly"
|
||||
" %d (since this uniform is not an array"
|
||||
" uniform), got an array of length %d", name,
|
||||
expectedElemSize,
|
||||
arrayLength);
|
||||
return false;
|
||||
}
|
||||
numElementsToUpload =
|
||||
NS_MIN(info.arraySize, arrayLength / expectedElemSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
|
||||
GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
|
||||
WebGLboolean aTranspose)
|
||||
{
|
||||
uint32_t expectedElemSize = (dim)*(dim);
|
||||
if (!IsContextStable())
|
||||
return false;
|
||||
nsCString nameString(name);
|
||||
nsCString suffix = NS_LITERAL_CSTRING(": location");
|
||||
nsCString concatenated = nameString + suffix;
|
||||
if (!ValidateUniformLocation(concatenated.get(), location_object))
|
||||
return false;
|
||||
location = location_object->Location();
|
||||
uint32_t uniformElemSize = location_object->ElementSize();
|
||||
if (expectedElemSize != uniformElemSize) {
|
||||
ErrorInvalidOperation("%s: this function expected a uniform of element size %d,"
|
||||
" got a uniform of element size %d", name,
|
||||
expectedElemSize,
|
||||
uniformElemSize);
|
||||
return false;
|
||||
}
|
||||
const WebGLUniformInfo& info = location_object->Info();
|
||||
if (arrayLength == 0 ||
|
||||
arrayLength % expectedElemSize)
|
||||
{
|
||||
ErrorInvalidValue("%s: expected an array of length a multiple"
|
||||
" of %d, got an array of length %d", name,
|
||||
expectedElemSize,
|
||||
arrayLength);
|
||||
return false;
|
||||
}
|
||||
if (!info.isArray &&
|
||||
arrayLength != expectedElemSize) {
|
||||
ErrorInvalidOperation("%s: expected an array of length exactly"
|
||||
" %d (since this uniform is not an array"
|
||||
" uniform), got an array of length %d", name,
|
||||
expectedElemSize,
|
||||
arrayLength);
|
||||
return false;
|
||||
}
|
||||
if (aTranspose) {
|
||||
ErrorInvalidValue("%s: transpose must be FALSE as per the "
|
||||
"OpenGL ES 2.0 spec", name);
|
||||
return false;
|
||||
}
|
||||
numElementsToUpload =
|
||||
NS_MIN(info.arraySize, arrayLength / (expectedElemSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return false;
|
||||
nsCString nameString(name);
|
||||
nsCString suffix = NS_LITERAL_CSTRING(": location");
|
||||
nsCString concatenated = nameString + suffix;
|
||||
if (!ValidateUniformLocation(concatenated.get(), location_object))
|
||||
return false;
|
||||
location = location_object->Location();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebGLContext::ValidateAttribIndex(WebGLuint index, const char *info)
|
||||
{
|
||||
if (index >= mAttribBuffers.Length()) {
|
||||
|
@ -1492,7 +1492,14 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
|
||||
if (oldScope && newScope != oldScope) {
|
||||
rv = nsContentUtils::ReparentContentWrappersInScope(cx, oldScope, newScope);
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> ignored;
|
||||
rv = xpc->ReparentWrappedNativeIfFound(cx, oldScope->GetGlobalJSObject(),
|
||||
newScope->GetGlobalJSObject(),
|
||||
static_cast<nsINode*>(this),
|
||||
getter_AddRefs(ignored));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = xpc->RescueOrphansInScope(cx, oldScope->GetGlobalJSObject());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
@ -793,7 +793,7 @@ class CGClassConstructHook(CGAbstractStaticMethod):
|
||||
JS::Value val = OBJECT_TO_JSVAL(obj);
|
||||
rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
|
||||
if (NS_FAILED(rv)) {
|
||||
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
return ThrowErrorMessage(cx, MSG_GLOBAL_NOT_NATIVE);
|
||||
}
|
||||
}
|
||||
"""
|
||||
@ -1639,8 +1639,8 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
|
||||
"""
|
||||
def __init__(self, descriptor, source, target):
|
||||
CastableObjectUnwrapper.__init__(self, descriptor, source, target,
|
||||
"return Throw<%s>(cx, rv);" %
|
||||
toStringBool(not descriptor.workers))
|
||||
"return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE," +
|
||||
'"%s");' % descriptor.name)
|
||||
|
||||
class CallbackObjectUnwrapper:
|
||||
"""
|
||||
@ -1651,8 +1651,9 @@ class CallbackObjectUnwrapper:
|
||||
"""
|
||||
def __init__(self, descriptor, source, target, codeOnFailure=None):
|
||||
if codeOnFailure is None:
|
||||
codeOnFailure = ("return Throw<%s>(cx, rv);" %
|
||||
toStringBool(not descriptor.workers))
|
||||
codeOnFailure = ("return ThrowErrorMessage(cx," +
|
||||
'MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' %
|
||||
descriptor.name)
|
||||
self.descriptor = descriptor
|
||||
self.substitution = { "nativeType" : descriptor.nativeType,
|
||||
"source" : source,
|
||||
@ -1908,7 +1909,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||
|
||||
templateBody = ("""JSObject* seq = &${val}.toObject();\n
|
||||
if (!IsArrayLike(cx, seq)) {
|
||||
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
return ThrowErrorMessage(cx, MSG_NOT_SEQUENCE);
|
||||
}
|
||||
uint32_t length;
|
||||
// JS_GetArrayLength actually works on all objects
|
||||
@ -1917,18 +1918,17 @@ if (!JS_GetArrayLength(cx, seq, &length)) {
|
||||
}
|
||||
Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
|
||||
if (!arr.SetCapacity(length)) {
|
||||
return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY);
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
jsval temp;
|
||||
if (!JS_GetElement(cx, seq, i, &temp)) {
|
||||
return false;
|
||||
}
|
||||
""" % (toStringBool(descriptorProvider.workers),
|
||||
""" % (elementDeclType.define(),
|
||||
elementDeclType.define(),
|
||||
elementDeclType.define(),
|
||||
arrayRef,
|
||||
toStringBool(descriptorProvider.workers)))
|
||||
arrayRef))
|
||||
|
||||
templateBody += CGIndenter(CGGeneric(
|
||||
string.Template(elementTemplate).substitute(
|
||||
@ -3489,8 +3489,9 @@ class CGMethodCall(CGThing):
|
||||
else:
|
||||
# Just throw; we have no idea what we're supposed to
|
||||
# do with this.
|
||||
caseBody.append(CGGeneric("return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);" %
|
||||
toStringBool(not descriptor.workers)))
|
||||
caseBody.append(CGGeneric(
|
||||
'return ThrowErrorMessage(cx, MSG_INVALID_ARG, "%s", "%s");'
|
||||
% (str(distinguishingIndex), str(argCount))))
|
||||
|
||||
argCountCases.append(CGCase(str(argCount),
|
||||
CGList(caseBody, "\n")))
|
||||
@ -3576,8 +3577,7 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
|
||||
|
||||
if unwrapFailureCode is None:
|
||||
self.unwrapFailureCode = ("return Throw<%s>(cx, rv);" %
|
||||
toStringBool(not descriptor.workers))
|
||||
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' % self.descriptor.name
|
||||
else:
|
||||
self.unwrapFailureCode = unwrapFailureCode
|
||||
|
||||
@ -5478,7 +5478,7 @@ class CGDictionary(CGThing):
|
||||
" JS::Value temp;\n"
|
||||
" bool isNull = val.isNullOrUndefined();\n"
|
||||
" if (!isNull && !val.isObject()) {\n"
|
||||
" return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
||||
" return ThrowErrorMessage(cx, MSG_NOT_OBJECT);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"${initMembers}\n"
|
||||
|
@ -29,3 +29,6 @@ MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
|
||||
MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.")
|
||||
MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.")
|
||||
MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
|
||||
MSG_DEF(MSG_NOT_SEQUENCE, 0, "object can not be converted to a sequence")
|
||||
MSG_DEF(MSG_INVALID_ARG, 2, "argument {0} is not valid for any of the {1}-argument overloads")
|
||||
MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, "global is not a native object")
|
||||
|
@ -62,6 +62,7 @@ MOCHITEST_FILES := \
|
||||
test_sequence_wrapping.html \
|
||||
file_bug775543.html \
|
||||
test_bug788369.html \
|
||||
test_bug742191.html \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
|
36
dom/bindings/test/test_bug742191.html
Normal file
36
dom/bindings/test/test_bug742191.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=742191
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for invalid argument object</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=742191">Mozilla Bug 742191</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 742191 **/
|
||||
function doTest() {
|
||||
var gotTypeError = false;
|
||||
var ctx = document.createElement("canvas").getContext("2d");
|
||||
try {
|
||||
ctx.drawImage({}, 0, 0);
|
||||
} catch(e) {
|
||||
if (e instanceof TypeError) {
|
||||
gotTypeError = true;
|
||||
}
|
||||
}
|
||||
|
||||
ok(gotTypeError, "passing an invalid argument should cause a type error!");
|
||||
}
|
||||
doTest();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -462,7 +462,10 @@ BrowserElementChild.prototype = {
|
||||
content.innerHeight, "rgb(255,255,255)");
|
||||
sendAsyncMsg('got-screenshot', {
|
||||
id: data.json.id,
|
||||
rv: canvas.toDataURL("image/png")
|
||||
// Hack around the fact that we can't specify opaque PNG, this requires
|
||||
// us to unpremultiply the alpha channel which is expensive on ARM
|
||||
// processors because they lack a hardware integer division instruction.
|
||||
rv: canvas.toDataURL("image/jpeg")
|
||||
});
|
||||
},
|
||||
|
||||
@ -621,6 +624,10 @@ BrowserElementChild.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove password and wyciwyg from uri.
|
||||
location = Cc["@mozilla.org/docshell/urifixup;1"]
|
||||
.getService(Ci.nsIURIFixup).createExposableURI(location);
|
||||
|
||||
sendAsyncMsg('locationchange', location.spec);
|
||||
},
|
||||
|
||||
|
@ -139,6 +139,9 @@ MOCHITEST_FILES = \
|
||||
file_browserElement_AppFramePermission.html \
|
||||
browserElement_AppFramePermission.js \
|
||||
test_browserElement_inproc_AppFramePermission.html \
|
||||
file_wyciwyg.html \
|
||||
browserElement_ExposableURI.js \
|
||||
test_browserElement_inproc_ExposableURI.html \
|
||||
$(NULL)
|
||||
|
||||
# Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
|
||||
@ -201,6 +204,7 @@ MOCHITEST_FILES += \
|
||||
test_browserElement_oop_RemoveBrowserElement.html \
|
||||
test_browserElement_oop_DOMRequestError.html \
|
||||
test_browserElement_oop_AppFramePermission.html \
|
||||
test_browserElement_oop_ExposableURI.html \
|
||||
$(NULL)
|
||||
endif #}
|
||||
endif #}
|
||||
|
57
dom/browser-element/mochitest/browserElement_ExposableURI.js
Normal file
57
dom/browser-element/mochitest/browserElement_ExposableURI.js
Normal file
@ -0,0 +1,57 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 795317: Test that the browser element sanitizes its URIs by removing the
|
||||
// "unexposable" parts before sending them in the locationchange event.
|
||||
|
||||
"use strict";
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe;
|
||||
|
||||
|
||||
function testPassword() {
|
||||
function locationchange(e) {
|
||||
var uri = e.detail;
|
||||
is(uri, 'http://mochi.test:8888/tests/dom/browser-element/mochitest/file_empty.html',
|
||||
"Username and password shouldn't be exposed in uri.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
iframe.addEventListener('mozbrowserlocationchange', locationchange);
|
||||
iframe.src = "http://iamuser:iampassword@mochi.test:8888/tests/dom/browser-element/mochitest/file_empty.html";
|
||||
}
|
||||
|
||||
function testWyciwyg() {
|
||||
var locationChangeCount = 0;
|
||||
|
||||
function locationchange(e) {
|
||||
// locationChangeCount:
|
||||
// 0 - the first load.
|
||||
// 1 - after document.write().
|
||||
if (locationChangeCount == 0) {
|
||||
locationChangeCount ++;
|
||||
} else if (locationChangeCount == 1) {
|
||||
var uri = e.detail;
|
||||
is(uri, 'http://mochi.test:8888/tests/dom/browser-element/mochitest/file_wyciwyg.html', "Scheme in string shouldn't be wyciwyg");
|
||||
iframe.removeEventListener('mozbrowserlocationchange', locationchange);
|
||||
SimpleTest.executeSoon(testPassword);
|
||||
}
|
||||
}
|
||||
|
||||
// file_wyciwyg.html calls document.write() to create a wyciwyg channel.
|
||||
iframe.src = 'file_wyciwyg.html';
|
||||
iframe.addEventListener('mozbrowserlocationchange', locationchange);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
document.body.appendChild(iframe);
|
||||
testWyciwyg();
|
||||
}
|
||||
|
||||
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
14
dom/browser-element/mochitest/file_wyciwyg.html
Normal file
14
dom/browser-element/mochitest/file_wyciwyg.html
Normal file
@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>test</title>
|
||||
<script type="text/javascript">
|
||||
addEventListener('load', function() {
|
||||
window.setTimeout(function() {
|
||||
document.write("test");
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=795317
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 795317</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=795317">Mozilla Bug 795317</a>
|
||||
|
||||
<script type="application/javascript;version1.7" src="browserElement_ExposableURI.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=795317
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 795317</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=795317">Mozilla Bug 795317</a>
|
||||
|
||||
<script type="application/javascript;version1.7" src="browserElement_ExposableURI.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -359,15 +359,11 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
|
||||
NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
|
||||
outputStream,
|
||||
4096*4);
|
||||
rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
|
||||
outputStream,
|
||||
4096*4);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!bufferedOutputStream) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
while (bufSize) {
|
||||
uint32_t wrote;
|
||||
rv = bufferedOutputStream->WriteFrom(aInputStream,
|
||||
|
@ -452,13 +452,9 @@
|
||||
"NodeFilter interface: constant SHOW_DOCUMENT_FRAGMENT on interface prototype object": true,
|
||||
"NodeFilter interface: constant SHOW_NOTATION on interface prototype object": true,
|
||||
"NodeFilter interface: operation acceptNode(Node)": true,
|
||||
"NodeList interface: attribute length": true,
|
||||
"HTMLCollection interface: attribute length": true,
|
||||
"DOMStringList interface: existence and properties of interface object": true,
|
||||
"DOMStringList interface: existence and properties of interface prototype object": true,
|
||||
"DOMStringList interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
"DOMStringList interface: attribute length": true,
|
||||
"DOMTokenList interface: attribute length": true,
|
||||
"Stringification of document.body.classList": true,
|
||||
"DOMSettableTokenList interface: attribute value": true
|
||||
"Stringification of document.body.classList": true
|
||||
}
|
||||
|
@ -1,17 +1,7 @@
|
||||
{
|
||||
"XMLHttpRequest interface constructor": true,
|
||||
"XMLHttpRequest interface: attribute onreadystatechange": true,
|
||||
"XMLHttpRequest interface: attribute readyState": true,
|
||||
"XMLHttpRequest interface: operation open(DOMString,DOMString,boolean,DOMString,DOMString)": true,
|
||||
"XMLHttpRequest interface: attribute timeout": true,
|
||||
"XMLHttpRequest interface: attribute withCredentials": true,
|
||||
"XMLHttpRequest interface: attribute upload": true,
|
||||
"XMLHttpRequest interface: operation send(union)": true,
|
||||
"XMLHttpRequest interface: attribute status": true,
|
||||
"XMLHttpRequest interface: attribute statusText": true,
|
||||
"XMLHttpRequest interface: attribute response": true,
|
||||
"XMLHttpRequest interface: attribute responseText": true,
|
||||
"XMLHttpRequest interface: attribute responseXML": true,
|
||||
"FormData interface: existence and properties of interface object": true,
|
||||
"FormData interface constructor": true,
|
||||
"FormData interface: existence and properties of interface prototype object": true,
|
||||
|
17
dom/media/tests/crashtests/791270.html
Normal file
17
dom/media/tests/crashtests/791270.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=791270
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple PeerConnection Video Test</title>
|
||||
<script type="application/javascript">
|
||||
var pc = new mozPeerConnection();
|
||||
pc.addStream(undefined);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
1
dom/media/tests/crashtests/crashtests.list
Normal file
1
dom/media/tests/crashtests/crashtests.list
Normal file
@ -0,0 +1 @@
|
||||
pref(media.peerconnection.enabled,true) load 791270.html
|
@ -349,7 +349,7 @@ let PaymentManager = {
|
||||
this.paymentFailed("CREATE_PAYMENT_GLUE_FAILED");
|
||||
return false;
|
||||
}
|
||||
glue.showPaymentFlow(paymentFlowInfo, this.paymentFailed);
|
||||
glue.showPaymentFlow(paymentFlowInfo, this.paymentFailed.bind(this));
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
|
@ -12,15 +12,17 @@ interface nsIPaymentUIGlueCallback : nsISupports
|
||||
void onresult(in DOMString result);
|
||||
};
|
||||
|
||||
[scriptable, uuid(c3ff92b3-f24f-4f93-afda-e92a112a80f8)]
|
||||
[scriptable, uuid(344e5442-7cc2-4636-bc42-e2249cb67813)]
|
||||
interface nsIPaymentUIGlue : nsISupports
|
||||
{
|
||||
// The 'paymentRequestsInfo' contains the payment request information
|
||||
// for each JWT provided via navigator.mozPay call.
|
||||
// for each JWT provided via navigator.mozPay call.
|
||||
void confirmPaymentRequest(in jsval paymentRequestsInfo,
|
||||
in nsIPaymentUIGlueCallback successCb,
|
||||
in nsIPaymentUIGlueCallback errorCb);
|
||||
|
||||
void showPaymentFlow(in nsIPaymentFlowInfo paymentFlowInfo,
|
||||
in nsIPaymentUIGlueCallback errorCb);
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
@ -7016,8 +7016,12 @@ let StkProactiveCmdHelper = {
|
||||
return null;
|
||||
}
|
||||
|
||||
let eventList = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
eventList.push(GsmPDUHelper.readHexOctet());
|
||||
}
|
||||
return {
|
||||
eventList: GsmPDUHelper.readHexOctetArray(length)
|
||||
eventList: eventList
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -363,6 +363,39 @@ add_test(function test_stk_proactive_command_poll_interval() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_stk_proactive_command_event_list() {
|
||||
let worker = newUint8Worker();
|
||||
let pduHelper = worker.GsmPDUHelper;
|
||||
let berHelper = worker.BerTlvHelper;
|
||||
let stkHelper = worker.StkProactiveCmdHelper;
|
||||
|
||||
let event_1 = [
|
||||
0xD0,
|
||||
0x0F,
|
||||
0x81, 0x03, 0x01, 0x05, 0x00,
|
||||
0x82, 0x02, 0x81, 0x82,
|
||||
0x99, 0x04, 0x00, 0x01, 0x02, 0x03];
|
||||
|
||||
for (let i = 0; i < event_1.length; i++) {
|
||||
pduHelper.writeHexOctet(event_1[i]);
|
||||
}
|
||||
|
||||
let berTlv = berHelper.decode(event_1.length);
|
||||
let ctlvs = berTlv.value;
|
||||
let tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
|
||||
do_check_eq(tlv.value.commandNumber, 0x01);
|
||||
do_check_eq(tlv.value.typeOfCommand, 0x05);
|
||||
do_check_eq(tlv.value.commandQualifier, 0x00);
|
||||
|
||||
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_EVENT_LIST, ctlvs);
|
||||
do_check_eq(Array.isArray(tlv.value.eventList), true);
|
||||
for (let i = 0; i < tlv.value.eventList.length; i++) {
|
||||
do_check_eq(tlv.value.eventList[i], i);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ComprehensionTlvHelper.getSizeOfLengthOctets
|
||||
*/
|
||||
@ -416,4 +449,5 @@ add_test(function test_write_length() {
|
||||
do_check_eq(pduHelper.readHexOctet(), length & 0xff);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1022,15 +1022,6 @@ nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
|
||||
nsRefPtr<PermissionKey> key = new PermissionKey(Substring(aHost, offset), aAppId, aIsInBrowserElement);
|
||||
entry = mPermissionTable.GetEntry(key);
|
||||
|
||||
if (!entry) {
|
||||
// This is a temporary fix to have Gaia working and allow a time frame to
|
||||
// update profiles. With this hack, if a permission isn't found for an app
|
||||
// the check will be done for the same host outside of any app.
|
||||
// TODO: remove this with bug 785632.
|
||||
key = new PermissionKey(Substring(aHost, offset), nsIScriptSecurityManager::NO_APP_ID, false);
|
||||
entry = mPermissionTable.GetEntry(key);
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
PermissionEntry permEntry = entry->GetPermission(aType);
|
||||
|
||||
|
@ -181,6 +181,10 @@ PollSensors()
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// FIXME: bug 802004, add proper support for the magnetic field sensor.
|
||||
if (buffer[i].type == SENSOR_TYPE_MAGNETIC_FIELD)
|
||||
continue;
|
||||
|
||||
NS_DispatchToMainThread(new SensorRunnable(buffer[i], sensors, size));
|
||||
}
|
||||
} while (true);
|
||||
|
@ -103,7 +103,7 @@ PrintBacktrace()
|
||||
int32_t OOM_traceIdx = 0;
|
||||
OOM_traceSize = backtrace(OOM_trace, JS_OOM_BACKTRACE_SIZE);
|
||||
OOM_traceSymbols = backtrace_symbols(OOM_trace, OOM_traceSize);
|
||||
|
||||
|
||||
if (!OOM_traceSymbols)
|
||||
return;
|
||||
|
||||
|
@ -21,7 +21,7 @@ BumpChunk::new_(size_t chunkSize)
|
||||
return NULL;
|
||||
BumpChunk *result = new (mem) BumpChunk(chunkSize - sizeof(BumpChunk));
|
||||
|
||||
/*
|
||||
/*
|
||||
* We assume that the alignment of sAlign is less than that of
|
||||
* the underlying memory allocator -- creating a new BumpChunk should
|
||||
* always satisfy the sAlign alignment constraint.
|
||||
|
@ -2668,7 +2668,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
|
||||
/* Initialize fun->script() so that the debugger has a valid fun->script(). */
|
||||
RootedFunction fun(cx, bce->script->function());
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
JS_ASSERT(!fun->script());
|
||||
JS_ASSERT(!fun->script().unsafeGet());
|
||||
fun->setScript(bce->script);
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, fun, singleton))
|
||||
return false;
|
||||
@ -4835,9 +4835,10 @@ EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
static JS_NEVER_INLINE bool
|
||||
EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
AssertCanGC();
|
||||
RootedFunction fun(cx, pn->pn_funbox->function());
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
if (fun->script()) {
|
||||
if (fun->script().unsafeGet()) {
|
||||
/*
|
||||
* This second pass is needed to emit JSOP_NOP with a source note
|
||||
* for the already-emitted function definition prolog opcode. See
|
||||
|
193
js/src/gc/Root.h
193
js/src/gc/Root.h
@ -79,6 +79,10 @@ namespace JS {
|
||||
|
||||
template <typename T> class MutableHandle;
|
||||
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
||||
JS_FRIEND_API(bool) InNoGCScope();
|
||||
|
||||
/*
|
||||
* Handle provides an implicit constructor for NullPtr so that, given:
|
||||
* foo(Handle<JSObject*> h);
|
||||
@ -316,6 +320,168 @@ class InternalHandle<T*>
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
template <typename T>
|
||||
class IntermediateNoGC
|
||||
{
|
||||
T t_;
|
||||
|
||||
public:
|
||||
IntermediateNoGC(const T &t) : t_(t) {
|
||||
EnterAssertNoGCScope();
|
||||
}
|
||||
IntermediateNoGC(const IntermediateNoGC &) {
|
||||
EnterAssertNoGCScope();
|
||||
}
|
||||
~IntermediateNoGC() {
|
||||
LeaveAssertNoGCScope();
|
||||
}
|
||||
|
||||
const T &operator->() { return t_; }
|
||||
operator const T &() { return t_; }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return<T> wraps GC things that are returned from accessor methods. The
|
||||
* wrapper helps to ensure correct rooting of the returned pointer and safe
|
||||
* access while unrooted.
|
||||
*
|
||||
* Example usage in a method declaration:
|
||||
*
|
||||
* class Foo {
|
||||
* HeapPtrScript script_;
|
||||
* ...
|
||||
* public:
|
||||
* Return<JSScript*> script() { return script_; }
|
||||
* };
|
||||
*
|
||||
* Example usage of method (1):
|
||||
*
|
||||
* Foo foo(...);
|
||||
* RootedScript script(cx, foo->script());
|
||||
*
|
||||
* Example usage of method (2):
|
||||
*
|
||||
* Foo foo(...);
|
||||
* foo->script()->needsArgsObj();
|
||||
*
|
||||
* The purpose of this class is to assert eagerly on incorrect use of GC thing
|
||||
* pointers. For example:
|
||||
*
|
||||
* RootedShape shape(cx, ...);
|
||||
* shape->parent.init(js_NewGCThing<Shape*>(cx, ...));
|
||||
*
|
||||
* In this expression, C++ is allowed to order these calls as follows:
|
||||
*
|
||||
* Call Effect
|
||||
* ---- ------
|
||||
* 1) RootedShape::operator-> Stores shape::ptr_ to stack.
|
||||
* 2) js_NewGCThing<Shape*> Triggers GC and compaction of shapes. This
|
||||
* moves shape::ptr_ to a new location.
|
||||
* 3) HeapPtrObject::init This call takes the relocated shape::ptr_
|
||||
* as |this|, crashing or, worse, corrupting
|
||||
* the program's state on the first access
|
||||
* to a member variable.
|
||||
*
|
||||
* If Shape::parent were an accessor function returning a Return<Shape*>, this
|
||||
* could not happen: Return ensures either immediate rooting or no GC within
|
||||
* the same expression.
|
||||
*/
|
||||
template <typename T>
|
||||
class Return
|
||||
{
|
||||
friend class Rooted<T>;
|
||||
|
||||
const T ptr_;
|
||||
|
||||
public:
|
||||
template <typename S>
|
||||
Return(const S &ptr,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
|
||||
: ptr_(ptr)
|
||||
{}
|
||||
|
||||
Return(NullPtr) : ptr_(NULL) {}
|
||||
|
||||
/*
|
||||
* |operator const T &| is the safest way to access a Return<T> without
|
||||
* rooting it first: it will assert when used outside of an AutoAssertNoGC
|
||||
* guard scope.
|
||||
*
|
||||
* Example:
|
||||
* AutoAssertNoGC nogc;
|
||||
* RawScript script = fun->script();
|
||||
*/
|
||||
operator const T &() const {
|
||||
JS_ASSERT(InNoGCScope());
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
/*
|
||||
* |operator->|'s result cannot be stored in a local variable, so it is safe
|
||||
* to use in a CanGC context iff no GC can occur anywhere within the same
|
||||
* expression (generally from one |;| to the next). |operator->| uses a
|
||||
* temporary object as a guard and will assert if a CanGC context is
|
||||
* encountered before the next C++ Sequence Point.
|
||||
*
|
||||
* INCORRECT:
|
||||
* fun->script()->bindings = myBindings->clone(cx, ...);
|
||||
*
|
||||
* The compiler is allowed to reorder |fun->script()::operator->()| above
|
||||
* the call to |clone(cx, ...)|. In this case, the RawScript C++ stores on
|
||||
* the stack may be corrupted by a GC under |clone|. The subsequent
|
||||
* dereference of this pointer to get |bindings| will result in an invalid
|
||||
* access. This wrapper ensures that such usage asserts in DEBUG builds when
|
||||
* it encounters this situation. Without this assertion, it is possible for
|
||||
* such access to corrupt program state instead of crashing immediately.
|
||||
*
|
||||
* CORRECT:
|
||||
* RootedScript clone(cx, myBindings->clone(cx, ...));
|
||||
* fun->script()->bindings = clone;
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
IntermediateNoGC<T> operator->() const {
|
||||
return IntermediateNoGC<T>(ptr_);
|
||||
}
|
||||
#else
|
||||
const T &operator->() const {
|
||||
return ptr_;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* |unsafeGet()| is unsafe for most uses. Although it performs similar
|
||||
* checking to |operator->|, its result can be stored to a local variable.
|
||||
* For this reason, it should only be used when it would be incorrect or
|
||||
* absurd to create a new Rooted for its use: e.g. for assertions.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
IntermediateNoGC<T> unsafeGet() const {
|
||||
return IntermediateNoGC<T>(ptr_);
|
||||
}
|
||||
#else
|
||||
const T &unsafeGet() const {
|
||||
return ptr_;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* |operator==| is safe to use in any context. It is present to allow:
|
||||
* JS_ASSERT(myScript == fun->script().unsafeGet());
|
||||
*
|
||||
* To be rewritten as:
|
||||
* JS_ASSERT(fun->script() == myScript);
|
||||
*
|
||||
* Note: the new order tells C++ to use |Return<JSScript*>::operator=|
|
||||
* instead of direct pointer comparison.
|
||||
*/
|
||||
bool operator==(const T &other) { return ptr_ == other; }
|
||||
bool operator==(const Return<T> &other) { return ptr_ == other.ptr_; }
|
||||
bool operator==(const JS::Handle<T> &other) { return ptr_ == other.get(); }
|
||||
inline bool operator==(const Rooted<T> &other);
|
||||
};
|
||||
|
||||
/*
|
||||
* By default, pointers should use the inheritance hierarchy to find their
|
||||
* ThingRootKind. Some pointer types are explicitly set in jspubtd.h so that
|
||||
@ -407,6 +573,15 @@ class Rooted : public RootedBase<T>
|
||||
init(cx);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
Rooted(JSContext *cx, const Return<S> &initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial.ptr_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
}
|
||||
|
||||
~Rooted()
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
@ -439,6 +614,13 @@ class Rooted : public RootedBase<T>
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
T & operator =(const Return<S> &value)
|
||||
{
|
||||
ptr = value.ptr_;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
Rooted<T> **stack, *prev;
|
||||
@ -449,6 +631,13 @@ class Rooted : public RootedBase<T>
|
||||
Rooted(const Rooted &) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
Return<T>::operator==(const Rooted<T> &other)
|
||||
{
|
||||
return ptr_ == other.get();
|
||||
}
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
@ -544,10 +733,6 @@ MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
||||
JS_FRIEND_API(bool) InNoGCScope();
|
||||
|
||||
/*
|
||||
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
|
||||
* attempted while the guard object is live. If you have a GC-unsafe operation
|
||||
|
@ -77,6 +77,8 @@ IonBailoutIterator::dump() const
|
||||
static JSScript*
|
||||
GetBailedJSScript(JSContext *cx)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
// Just after the frame conversion, we can safely interpret the ionTop as JS
|
||||
// frame because it targets the bailed JS frame converted to an exit frame.
|
||||
IonJSFrameLayout *frame = reinterpret_cast<IonJSFrameLayout*>(cx->runtime->ionTop);
|
||||
@ -96,6 +98,7 @@ GetBailedJSScript(JSContext *cx)
|
||||
void
|
||||
StackFrame::initFromBailout(JSContext *cx, SnapshotIterator &iter)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
uint32 exprStackSlots = iter.slots() - script()->nfixed;
|
||||
|
||||
#ifdef TRACK_SNAPSHOTS
|
||||
@ -182,6 +185,8 @@ StackFrame::initFromBailout(JSContext *cx, SnapshotIterator &iter)
|
||||
static StackFrame *
|
||||
PushInlinedFrame(JSContext *cx, StackFrame *callerFrame)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
// Grab the callee object out of the caller's frame, which has already been restored.
|
||||
// N.B. we currently assume that the caller frame is at a JSOP_CALL pc for the caller frames,
|
||||
// which will not be the case when we inline getters (in which case it would be a
|
||||
@ -191,10 +196,10 @@ PushInlinedFrame(JSContext *cx, StackFrame *callerFrame)
|
||||
int callerArgc = GET_ARGC(regs.pc);
|
||||
const Value &calleeVal = regs.sp[-callerArgc - 2];
|
||||
|
||||
JSFunction *fun = calleeVal.toObject().toFunction();
|
||||
JSScript *script = fun->script();
|
||||
RootedFunction fun(cx, calleeVal.toObject().toFunction());
|
||||
RootedScript script(cx, fun->script());
|
||||
CallArgs inlineArgs = CallArgsFromSp(callerArgc, regs.sp);
|
||||
|
||||
|
||||
// Bump the stack pointer to make it look like the inline args have been pushed, but they will
|
||||
// really get filled in by RestoreOneFrame.
|
||||
regs.sp = inlineArgs.end();
|
||||
@ -209,7 +214,7 @@ PushInlinedFrame(JSContext *cx, StackFrame *callerFrame)
|
||||
StackFrame *fp = cx->stack.fp();
|
||||
JS_ASSERT(fp == regs.fp());
|
||||
JS_ASSERT(fp->prev() == callerFrame);
|
||||
|
||||
|
||||
fp->formals()[-2].setObject(*fun);
|
||||
|
||||
return fp;
|
||||
@ -218,6 +223,7 @@ PushInlinedFrame(JSContext *cx, StackFrame *callerFrame)
|
||||
static uint32
|
||||
ConvertFrames(JSContext *cx, IonActivation *activation, IonBailoutIterator &it)
|
||||
{
|
||||
AssertCanGC();
|
||||
IonSpew(IonSpew_Bailouts, "Bailing out %s:%u, IonScript %p",
|
||||
it.script()->filename, it.script()->lineno, (void *) it.ionScript());
|
||||
IonSpew(IonSpew_Bailouts, " reading from snapshot offset %u size %u",
|
||||
@ -253,7 +259,7 @@ ConvertFrames(JSContext *cx, IonActivation *activation, IonBailoutIterator &it)
|
||||
// conjunction with inline-OSR from within bailouts (since each Ion
|
||||
// activation must be tied to a unique JSStackFrame for StackIter to
|
||||
// work).
|
||||
//
|
||||
//
|
||||
// Note: If the entry frame is a placeholder (a stub frame pushed for
|
||||
// JM -> Ion calls), then we cannot re-use it as it does not have
|
||||
// enough slots.
|
||||
@ -318,7 +324,7 @@ ConvertFrames(JSContext *cx, IonActivation *activation, IonBailoutIterator &it)
|
||||
// we flag it here manually that the entry has happened.
|
||||
case Bailout_ArgumentCheck:
|
||||
fp->unsetPushedSPSFrame();
|
||||
Probes::enterScript(cx, fp->script(), fp->script()->function(), fp);
|
||||
Probes::enterScript(cx, fp->script().unsafeGet(), fp->script()->function(), fp);
|
||||
return BAILOUT_RETURN_ARGUMENT_CHECK;
|
||||
}
|
||||
|
||||
@ -351,6 +357,7 @@ EnsureExitFrame(IonCommonFrameLayout *frame)
|
||||
uint32
|
||||
ion::Bailout(BailoutStack *sp)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
// We don't have an exit frame.
|
||||
cx->runtime->ionTop = NULL;
|
||||
@ -373,6 +380,7 @@ ion::Bailout(BailoutStack *sp)
|
||||
uint32
|
||||
ion::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut)
|
||||
{
|
||||
AssertCanGC();
|
||||
sp->checkInvariants();
|
||||
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
@ -495,7 +503,7 @@ uint32
|
||||
ion::RecompileForInlining()
|
||||
{
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
JSScript *script = cx->fp()->script();
|
||||
RawScript script = cx->fp()->script().unsafeGet();
|
||||
|
||||
IonSpew(IonSpew_Inlining, "Recompiling script to inline calls %s:%d", script->filename,
|
||||
script->lineno);
|
||||
|
@ -308,7 +308,8 @@ CodeGenerator::visitLambda(LLambda *lir)
|
||||
|
||||
JS_STATIC_ASSERT(offsetof(JSFunction, flags) == offsetof(JSFunction, nargs) + 2);
|
||||
masm.store32(Imm32(u.word), Address(output, offsetof(JSFunction, nargs)));
|
||||
masm.storePtr(ImmGCPtr(fun->script()), Address(output, JSFunction::offsetOfNativeOrScript()));
|
||||
masm.storePtr(ImmGCPtr(fun->script().unsafeGet()),
|
||||
Address(output, JSFunction::offsetOfNativeOrScript()));
|
||||
masm.storePtr(scopeChain, Address(output, JSFunction::offsetOfEnvironment()));
|
||||
masm.storePtr(ImmGCPtr(fun->displayAtom()), Address(output, JSFunction::offsetOfAtom()));
|
||||
|
||||
@ -2900,6 +2901,7 @@ CodeGenerator::visitGetArgument(LGetArgument *lir)
|
||||
bool
|
||||
CodeGenerator::generate()
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
|
||||
unsigned slots = graph.localSlotCount() +
|
||||
@ -2941,7 +2943,7 @@ CodeGenerator::generate()
|
||||
// We encode safepoints after the OSI-point offsets have been determined.
|
||||
encodeSafepoints();
|
||||
|
||||
JSScript *script = gen->info().script();
|
||||
RootedScript script(cx, gen->info().script());
|
||||
JS_ASSERT(!script->hasIonScript());
|
||||
|
||||
uint32 scriptFrameSize = frameClass_ == FrameSizeClass::None()
|
||||
@ -4209,6 +4211,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty *ins)
|
||||
bool
|
||||
CodeGenerator::visitFunctionBoundary(LFunctionBoundary *lir)
|
||||
{
|
||||
AssertCanGC();
|
||||
Register temp = ToRegister(lir->temp()->output());
|
||||
|
||||
switch (lir->type()) {
|
||||
|
@ -290,6 +290,8 @@ IonActivation::~IonActivation()
|
||||
IonCode *
|
||||
IonCode::New(JSContext *cx, uint8 *code, uint32 bufferSize, JSC::ExecutablePool *pool)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
IonCode *codeObj = gc::NewGCThing<IonCode>(cx, gc::FINALIZE_IONCODE, sizeof(IonCode));
|
||||
if (!codeObj) {
|
||||
pool->release();
|
||||
@ -909,6 +911,7 @@ class AutoDestroyAllocator
|
||||
void
|
||||
AttachFinishedCompilations(JSContext *cx)
|
||||
{
|
||||
AssertCanGC();
|
||||
IonCompartment *ion = cx->compartment->ionCompartment();
|
||||
if (!ion)
|
||||
return;
|
||||
@ -924,7 +927,7 @@ AttachFinishedCompilations(JSContext *cx)
|
||||
IonBuilder *builder = compilations.popCopy();
|
||||
|
||||
if (builder->lir) {
|
||||
JSScript *script = builder->script();
|
||||
RootedScript script(cx, builder->script());
|
||||
IonContext ictx(cx, cx->compartment, &builder->temp());
|
||||
|
||||
CodeGenerator codegen(builder, *builder->lir);
|
||||
@ -961,6 +964,7 @@ static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
|
||||
static bool
|
||||
IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
|
||||
{
|
||||
AssertCanGC();
|
||||
#if JS_TRACE_LOGGING
|
||||
AutoTraceLog logger(TraceLogging::defaultLogger(),
|
||||
TraceLogging::ION_COMPILE_START,
|
||||
@ -1004,7 +1008,7 @@ IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc,
|
||||
IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &oracle, info);
|
||||
JS_ASSERT(!builder->script()->ion);
|
||||
|
||||
IonSpewNewFunction(graph, builder->script());
|
||||
IonSpewNewFunction(graph, builder->script().unsafeGet());
|
||||
|
||||
if (!builder->build()) {
|
||||
IonSpew(IonSpew_Abort, "Builder failed to build.");
|
||||
@ -1294,6 +1298,7 @@ ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script)
|
||||
return Method_Error;
|
||||
|
||||
// This can GC, so afterward, script->ion is not guaranteed to be valid.
|
||||
AssertCanGC();
|
||||
if (!cx->compartment->ionCompartment()->enterJIT(cx))
|
||||
return Method_Error;
|
||||
|
||||
@ -1306,6 +1311,7 @@ ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script)
|
||||
static IonExecStatus
|
||||
EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_CHECK_RECURSION(cx, return IonExec_Error);
|
||||
JS_ASSERT(ion::IsEnabled(cx));
|
||||
JS_ASSERT(CheckFrame(fp));
|
||||
@ -1345,7 +1351,7 @@ EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
|
||||
}
|
||||
calleeToken = CalleeToToken(&fp->callee());
|
||||
} else {
|
||||
calleeToken = CalleeToToken(fp->script());
|
||||
calleeToken = CalleeToToken(fp->script().unsafeGet());
|
||||
}
|
||||
|
||||
// Caller must construct |this| before invoking the Ion function.
|
||||
@ -1385,7 +1391,8 @@ EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
|
||||
IonExecStatus
|
||||
ion::Cannon(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
JSScript *script = fp->script();
|
||||
AssertCanGC();
|
||||
RootedScript script(cx, fp->script());
|
||||
IonScript *ion = script->ion;
|
||||
IonCode *code = ion->method();
|
||||
void *jitcode = code->raw();
|
||||
@ -1416,7 +1423,8 @@ ion::Cannon(JSContext *cx, StackFrame *fp)
|
||||
IonExecStatus
|
||||
ion::SideCannon(JSContext *cx, StackFrame *fp, jsbytecode *pc)
|
||||
{
|
||||
JSScript *script = fp->script();
|
||||
AssertCanGC();
|
||||
RootedScript script(cx, fp->script());
|
||||
IonScript *ion = script->ion;
|
||||
IonCode *code = ion->method();
|
||||
void *osrcode = code->raw() + ion->osrEntryOffset();
|
||||
@ -1451,7 +1459,7 @@ ion::FastInvoke(JSContext *cx, HandleFunction fun, CallArgs &args)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return IonExec_Error);
|
||||
|
||||
HandleScript script = fun->script();
|
||||
RootedScript script(cx, fun->script());
|
||||
IonScript *ion = script->ionScript();
|
||||
IonCode *code = ion->method();
|
||||
void *jitcode = code->raw();
|
||||
@ -1506,6 +1514,7 @@ ion::FastInvoke(JSContext *cx, HandleFunction fun, CallArgs &args)
|
||||
static void
|
||||
InvalidateActivation(FreeOp *fop, uint8 *ionTop, bool invalidateAll)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
IonSpew(IonSpew_Invalidate, "BEGIN invalidating activation");
|
||||
|
||||
size_t frameno = 1;
|
||||
@ -1551,7 +1560,7 @@ InvalidateActivation(FreeOp *fop, uint8 *ionTop, bool invalidateAll)
|
||||
if (it.checkInvalidation())
|
||||
continue;
|
||||
|
||||
JSScript *script = it.script();
|
||||
RawScript script = it.script();
|
||||
if (!script->hasIonScript())
|
||||
continue;
|
||||
|
||||
|
@ -146,11 +146,13 @@ IonBuilder::CFGState::LookupSwitch(jsbytecode *exitpc)
|
||||
JSFunction *
|
||||
IonBuilder::getSingleCallTarget(uint32 argc, jsbytecode *pc)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script(), argc, pc);
|
||||
if (!calleeTypes)
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = calleeTypes->getSingleton();
|
||||
RawObject obj = calleeTypes->getSingleton();
|
||||
if (!obj || !obj->isFunction())
|
||||
return NULL;
|
||||
|
||||
@ -186,6 +188,8 @@ IonBuilder::getPolyCallTargets(uint32 argc, jsbytecode *pc,
|
||||
bool
|
||||
IonBuilder::canInlineTarget(JSFunction *target)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
if (!target->isInterpreted()) {
|
||||
IonSpew(IonSpew_Inlining, "Cannot inline due to non-interpreted");
|
||||
return false;
|
||||
@ -196,7 +200,7 @@ IonBuilder::canInlineTarget(JSFunction *target)
|
||||
return false;
|
||||
}
|
||||
|
||||
JSScript *inlineScript = target->script();
|
||||
RootedScript inlineScript(cx, target->script());
|
||||
|
||||
if (!inlineScript->canIonCompile()) {
|
||||
IonSpew(IonSpew_Inlining, "Cannot inline due to disable Ion compilation");
|
||||
@ -756,6 +760,8 @@ IonBuilder::markPhiBytecodeUses(jsbytecode *pc)
|
||||
bool
|
||||
IonBuilder::inspectOpcode(JSOp op)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
// Don't compile fat opcodes, run the decomposed version instead.
|
||||
if (js_CodeSpec[op].format & JOF_DECOMPOSE)
|
||||
return true;
|
||||
@ -2797,6 +2803,8 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32 argc, bool constructi
|
||||
MConstant *constFun, MBasicBlock *bottom,
|
||||
Vector<MDefinition *, 8, IonAllocPolicy> &retvalDefns)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
// Rewrite the stack position containing the function with the constant
|
||||
// function definition, before we take the inlineResumePoint
|
||||
current->rewriteAtDepth(-((int) argc + 2), constFun);
|
||||
@ -2822,7 +2830,8 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32 argc, bool constructi
|
||||
|
||||
// Compilation information is allocated for the duration of the current tempLifoAlloc
|
||||
// lifetime.
|
||||
CompileInfo *info = cx->tempLifoAlloc().new_<CompileInfo>(callee->script(), callee,
|
||||
RootedScript calleeScript(cx, callee->script());
|
||||
CompileInfo *info = cx->tempLifoAlloc().new_<CompileInfo>(calleeScript.get(), callee,
|
||||
(jsbytecode *)NULL, constructing);
|
||||
if (!info)
|
||||
return false;
|
||||
@ -2831,7 +2840,7 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32 argc, bool constructi
|
||||
AutoAccumulateExits aae(graph(), saveExits);
|
||||
|
||||
TypeInferenceOracle oracle;
|
||||
if (!oracle.init(cx, callee->script()))
|
||||
if (!oracle.init(cx, calleeScript))
|
||||
return false;
|
||||
|
||||
IonBuilder inlineBuilder(cx, &temp(), &graph(), &oracle,
|
||||
@ -2887,6 +2896,8 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32 argc, bool constructi
|
||||
bool
|
||||
IonBuilder::makeInliningDecision(AutoObjectVector &targets, uint32 argc)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
if (inliningDepth >= js_IonOptions.maxInlineDepth)
|
||||
return false;
|
||||
|
||||
@ -2906,12 +2917,14 @@ IonBuilder::makeInliningDecision(AutoObjectVector &targets, uint32 argc)
|
||||
uint32_t totalSize = 0;
|
||||
uint32_t checkUses = js_IonOptions.usesBeforeInlining;
|
||||
bool allFunctionsAreSmall = true;
|
||||
RootedFunction target(cx);
|
||||
RootedScript script(cx);
|
||||
for (size_t i = 0; i < targets.length(); i++) {
|
||||
JSFunction *target = targets[i]->toFunction();
|
||||
target = targets[i]->toFunction();
|
||||
if (!target->isInterpreted())
|
||||
return false;
|
||||
|
||||
JSScript *script = target->script();
|
||||
script = target->script();
|
||||
uint32_t calleeUses = script->getUseCount();
|
||||
|
||||
if (target->nargs < argc) {
|
||||
@ -3530,7 +3543,7 @@ IonBuilder::createThisScriptedSingleton(HandleFunction target, HandleObject prot
|
||||
types::TypeObject *type = proto->getNewType(cx, target);
|
||||
if (!type)
|
||||
return NULL;
|
||||
if (!types::TypeScript::ThisTypes(target->script())->hasType(types::Type::ObjectType(type)))
|
||||
if (!types::TypeScript::ThisTypes(target->script().unsafeGet())->hasType(types::Type::ObjectType(type)))
|
||||
return NULL;
|
||||
|
||||
RootedObject templateObject(cx, js_CreateThisForFunctionWithProto(cx, target, proto));
|
||||
@ -3695,6 +3708,8 @@ IonBuilder::jsop_funapply(uint32 argc)
|
||||
bool
|
||||
IonBuilder::jsop_call(uint32 argc, bool constructing)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
// Acquire known call target if existent.
|
||||
AutoObjectVector targets(cx);
|
||||
uint32_t numTargets = getPolyCallTargets(argc, pc, targets, 4);
|
||||
|
@ -433,7 +433,7 @@ class IonBuilder : public MIRGenerator
|
||||
|
||||
void clearForBackEnd();
|
||||
|
||||
JSScript *script() const { return script_; }
|
||||
Return<JSScript*> script() const { return script_; }
|
||||
|
||||
private:
|
||||
JSContext *cx;
|
||||
|
@ -1313,14 +1313,15 @@ static inline void
|
||||
GenerateScopeChainGuard(MacroAssembler &masm, JSObject *scopeObj,
|
||||
Register scopeObjReg, Shape *shape, Label *failures)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (scopeObj->isCall()) {
|
||||
// We can skip a guard on the call object if the script's bindings are
|
||||
// guaranteed to be immutable (and thus cannot introduce shadowing
|
||||
// variables).
|
||||
CallObject *callObj = &scopeObj->asCall();
|
||||
if (!callObj->isForEval()) {
|
||||
JSFunction *fun = &callObj->callee();
|
||||
JSScript *script = fun->script();
|
||||
RawFunction fun = &callObj->callee();
|
||||
RawScript script = fun->script();
|
||||
if (!script->funHasExtensibleScope)
|
||||
return;
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ IonFrameIterator::frameSize() const
|
||||
inline JSScript *
|
||||
GetTopIonJSScript(JSContext *cx, const SafepointIndex **safepointIndexOut, void **returnAddrOut)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
IonFrameIterator iter(cx->runtime->ionTop);
|
||||
JS_ASSERT(iter.type() == IonFrame_Exit);
|
||||
++iter;
|
||||
|
@ -29,6 +29,7 @@ using namespace js::ion;
|
||||
JSScript *
|
||||
ion::MaybeScriptFromCalleeToken(CalleeToken token)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
switch (GetCalleeTokenTag(token)) {
|
||||
case CalleeToken_Script:
|
||||
return CalleeTokenToScript(token);
|
||||
@ -67,8 +68,9 @@ IonFrameIterator::checkInvalidation() const
|
||||
bool
|
||||
IonFrameIterator::checkInvalidation(IonScript **ionScriptOut) const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
uint8 *returnAddr = returnAddressToFp();
|
||||
JSScript *script = this->script();
|
||||
RawScript script = this->script();
|
||||
// N.B. the current IonScript is not the same as the frame's
|
||||
// IonScript if the frame has since been invalidated.
|
||||
IonScript *currentIonScript = script->ion;
|
||||
@ -170,8 +172,9 @@ IonFrameIterator::isEntryJSFrame() const
|
||||
JSScript *
|
||||
IonFrameIterator::script() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(isScripted());
|
||||
JSScript *script = MaybeScriptFromCalleeToken(calleeToken());
|
||||
RawScript script = MaybeScriptFromCalleeToken(calleeToken());
|
||||
JS_ASSERT(script);
|
||||
return script;
|
||||
}
|
||||
@ -260,6 +263,7 @@ IonFrameIterator::machineState() const
|
||||
static void
|
||||
CloseLiveIterator(JSContext *cx, const InlineFrameIterator &frame, uint32 localSlot)
|
||||
{
|
||||
AssertCanGC();
|
||||
SnapshotIterator si = frame.snapshotIterator();
|
||||
|
||||
// Skip stack slots until we reach the iterator object.
|
||||
@ -281,7 +285,8 @@ CloseLiveIterator(JSContext *cx, const InlineFrameIterator &frame, uint32 localS
|
||||
static void
|
||||
CloseLiveIterators(JSContext *cx, const InlineFrameIterator &frame)
|
||||
{
|
||||
JSScript *script = frame.script();
|
||||
AssertCanGC();
|
||||
RootedScript script(cx, frame.script());
|
||||
jsbytecode *pc = frame.pc();
|
||||
|
||||
if (!script->hasTrynotes())
|
||||
@ -311,6 +316,7 @@ CloseLiveIterators(JSContext *cx, const InlineFrameIterator &frame)
|
||||
void
|
||||
ion::HandleException(ResumeFromException *rfe)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
|
||||
IonSpew(IonSpew_Invalidate, "handling exception");
|
||||
@ -331,7 +337,8 @@ ion::HandleException(ResumeFromException *rfe)
|
||||
// When profiling, each frame popped needs a notification that
|
||||
// the function has exited, so invoke the probe that a function
|
||||
// is exiting.
|
||||
JSScript *script = frames.script();
|
||||
AutoAssertNoGC nogc;
|
||||
RawScript script = frames.script();
|
||||
Probes::exitScript(cx, script, script->function(), NULL);
|
||||
if (!frames.more())
|
||||
break;
|
||||
@ -900,6 +907,7 @@ InlineFrameIterator::InlineFrameIterator(const IonFrameIterator *iter)
|
||||
void
|
||||
InlineFrameIterator::findNextFrame()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(more());
|
||||
|
||||
si_ = start_;
|
||||
@ -1141,6 +1149,7 @@ struct DumpOp {
|
||||
void
|
||||
InlineFrameIterator::dump() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (more())
|
||||
fprintf(stderr, " JS frame (inlined)\n");
|
||||
else
|
||||
|
@ -29,6 +29,7 @@ class Linker
|
||||
}
|
||||
|
||||
IonCode *newCode(JSContext *cx, IonCompartment *comp) {
|
||||
AssertCanGC();
|
||||
#ifndef JS_CPU_ARM
|
||||
masm.flush();
|
||||
#endif
|
||||
|
@ -551,7 +551,8 @@ TypeInferenceOracle::canInlineCall(JSScript *caller, jsbytecode *pc)
|
||||
bool
|
||||
TypeInferenceOracle::canEnterInlinedFunction(JSFunction *target)
|
||||
{
|
||||
JSScript *script = target->script();
|
||||
AssertCanGC();
|
||||
RootedScript script(cx, target->script());
|
||||
if (!script->hasAnalysis() || !script->analysis()->ranInference())
|
||||
return false;
|
||||
|
||||
|
@ -354,6 +354,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint *ins, uint32 *callPointOffset)
|
||||
bool
|
||||
CodeGeneratorShared::callVM(const VMFunction &fun, LInstruction *ins, const Register *dynStack)
|
||||
{
|
||||
AssertCanGC();
|
||||
#ifdef DEBUG
|
||||
if (ins->mirRaw()) {
|
||||
JS_ASSERT(ins->mirRaw()->isInstruction());
|
||||
|
@ -510,6 +510,7 @@ template <class ArgSeq, class StoreOutputTo>
|
||||
bool
|
||||
CodeGeneratorShared::visitOutOfLineCallVM(OutOfLineCallVM<ArgSeq, StoreOutputTo> *ool)
|
||||
{
|
||||
AssertCanGC();
|
||||
LInstruction *lir = ool->lir();
|
||||
|
||||
saveLive(lir);
|
||||
|
@ -386,6 +386,7 @@ IonCompartment::generateBailoutHandler(JSContext *cx)
|
||||
IonCode *
|
||||
IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
{
|
||||
AssertCanGC();
|
||||
typedef MoveResolver::MoveOperand MoveOperand;
|
||||
|
||||
JS_ASSERT(!StackKeptAligned);
|
||||
|
@ -7225,6 +7225,8 @@ JS_IsIdentifier(JSContext *cx, JSString *str, JSBool *isIdentifier)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DescribeScriptedCaller(JSContext *cx, JSScript **script, unsigned *lineno)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (script)
|
||||
*script = NULL;
|
||||
if (lineno)
|
||||
|
@ -561,6 +561,8 @@ static void
|
||||
ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
/*
|
||||
* Check the error report, and set a JavaScript-catchable exception
|
||||
* if the error is defined to have an associated exception. If an
|
||||
@ -605,6 +607,8 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
static void
|
||||
PopulateReportBlame(JSContext *cx, JSErrorReport *report)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* Walk stack until we find a frame that is associated with a non-builtin
|
||||
* rather than a builtin frame.
|
||||
@ -628,6 +632,8 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
|
||||
void
|
||||
js_ReportOutOfMemory(JSContext *cx)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
cx->runtime->hadOutOfMemory = true;
|
||||
|
||||
JSErrorReport report;
|
||||
|
@ -410,8 +410,9 @@ JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun)
|
||||
extern JS_PUBLIC_API(uintptr_t *)
|
||||
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp)
|
||||
{
|
||||
RootedScript script(cx, fun->script());
|
||||
BindingVector bindings(cx);
|
||||
if (!FillBindingVector(fun->script(), &bindings))
|
||||
if (!FillBindingVector(script, &bindings))
|
||||
return NULL;
|
||||
|
||||
/* Munge data into the API this method implements. Avert your eyes! */
|
||||
@ -450,6 +451,7 @@ JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark)
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
return fun->maybeScript();
|
||||
}
|
||||
|
||||
@ -498,6 +500,7 @@ JS_BrokenFrameIterator(JSContext *cx, JSStackFrame **iteratorp)
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_GetFrameScript(JSContext *cx, JSStackFrame *fpArg)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
return Valueify(fpArg)->script();
|
||||
}
|
||||
|
||||
@ -532,6 +535,7 @@ JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fpArg)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetTopFrameAnnotation(JSContext *cx, void *annotation)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StackFrame *fp = cx->fp();
|
||||
JS_ASSERT_IF(fp->beginsIonActivation(), !fp->annotation());
|
||||
|
||||
@ -542,7 +546,7 @@ JS_SetTopFrameAnnotation(JSContext *cx, void *annotation)
|
||||
// because we will never EnterIon on a frame with an annotation.
|
||||
fp->setAnnotation(annotation);
|
||||
|
||||
JSScript *script = fp->script();
|
||||
RawScript script = fp->script();
|
||||
|
||||
ReleaseAllJITCode(cx->runtime->defaultFreeOp());
|
||||
|
||||
@ -671,6 +675,7 @@ JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fpArg, jsval rval)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StackFrame *fp = Valueify(fpArg);
|
||||
#ifdef JS_METHODJIT
|
||||
JS_ASSERT(fp->script()->debugMode);
|
||||
@ -1006,9 +1011,8 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
|
||||
JS_PUBLIC_API(size_t)
|
||||
JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = sizeof *fun;
|
||||
AutoAssertNoGC nogc;
|
||||
size_t nbytes = sizeof *fun;
|
||||
nbytes += JS_GetObjectTotalSize(cx, fun);
|
||||
if (fun->isInterpreted())
|
||||
nbytes += JS_GetScriptTotalSize(cx, fun->script());
|
||||
@ -1175,11 +1179,13 @@ JS_UnwrapObjectAndInnerize(JSObject *obj)
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_CallContextDebugHandler(JSContext *cx)
|
||||
{
|
||||
AssertCanGC();
|
||||
ScriptFrameIter iter(cx);
|
||||
JS_ASSERT(!iter.done());
|
||||
|
||||
jsval rval;
|
||||
switch (js::CallContextDebugHandler(cx, iter.script(), iter.pc(), &rval)) {
|
||||
RootedValue rval(cx);
|
||||
RootedScript script(cx, iter.script());
|
||||
switch (js::CallContextDebugHandler(cx, script, iter.pc(), rval.address())) {
|
||||
case JSTRAP_ERROR:
|
||||
JS_ClearPendingException(cx);
|
||||
return JS_FALSE;
|
||||
@ -1196,6 +1202,7 @@ js_CallContextDebugHandler(JSContext *cx)
|
||||
JS_PUBLIC_API(StackDescription *)
|
||||
JS::DescribeStack(JSContext *cx, unsigned maxFrames)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
Vector<FrameDescription> frames(cx);
|
||||
|
||||
for (ScriptFrameIter i(cx); !i.done(); ++i) {
|
||||
@ -1272,7 +1279,9 @@ static char *
|
||||
FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
JSBool showArgs, JSBool showLocals, JSBool showThisProps)
|
||||
{
|
||||
JSScript* script = iter.script();
|
||||
AssertCanGC();
|
||||
|
||||
RootedScript script(cx, iter.script());
|
||||
jsbytecode* pc = iter.pc();
|
||||
|
||||
RootedObject scopeChain(cx, iter.scopeChain());
|
||||
@ -1280,12 +1289,12 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
|
||||
const char *filename = script->filename;
|
||||
unsigned lineno = PCToLineNumber(script, pc);
|
||||
JSFunction *fun = iter.maybeCallee();
|
||||
JSString *funname = NULL;
|
||||
RootedFunction fun(cx, iter.maybeCallee());
|
||||
RootedString funname(cx);
|
||||
if (fun)
|
||||
funname = fun->atom();
|
||||
|
||||
JSObject *callObj = NULL;
|
||||
RootedObject callObj(cx);
|
||||
AutoPropertyDescArray callProps(cx);
|
||||
|
||||
if (!iter.isIon() && (showArgs || showLocals)) {
|
||||
@ -1294,7 +1303,7 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
callProps.fetch(callObj);
|
||||
}
|
||||
|
||||
Value thisVal = UndefinedValue();
|
||||
RootedValue thisVal(cx);
|
||||
AutoPropertyDescArray thisProps(cx);
|
||||
if (iter.computeThis()) {
|
||||
thisVal = iter.thisv();
|
||||
@ -1340,11 +1349,11 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
}
|
||||
|
||||
// print any unnamed trailing args (found in 'arguments' object)
|
||||
Value val;
|
||||
if (JS_GetProperty(cx, callObj, "arguments", &val) && val.isObject()) {
|
||||
RootedValue val(cx);
|
||||
if (JS_GetProperty(cx, callObj, "arguments", val.address()) && val.isObject()) {
|
||||
uint32_t argCount;
|
||||
JSObject* argsObj = &val.toObject();
|
||||
if (JS_GetProperty(cx, argsObj, "length", &val) &&
|
||||
RootedObject argsObj(cx, &val.toObject());
|
||||
if (JS_GetProperty(cx, argsObj, "length", val.address()) &&
|
||||
ToUint32(cx, val, &argCount) &&
|
||||
argCount > namedArgCount)
|
||||
{
|
||||
@ -1352,7 +1361,7 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
char number[8];
|
||||
JS_snprintf(number, 8, "%d", (int) k);
|
||||
|
||||
if (JS_GetProperty(cx, argsObj, number, &val)) {
|
||||
if (JS_GetProperty(cx, argsObj, number, val.address())) {
|
||||
JSAutoByteString valueBytes;
|
||||
const char *value = FormatValue(cx, val, valueBytes);
|
||||
buf = JS_sprintf_append(buf, "%s%s%s%s",
|
||||
@ -1401,7 +1410,8 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
if (showLocals) {
|
||||
if (!thisVal.isUndefined()) {
|
||||
JSAutoByteString thisValBytes;
|
||||
if (JSString* thisValStr = ToString(cx, thisVal)) {
|
||||
RootedString thisValStr(cx, ToString(cx, thisVal));
|
||||
if (thisValStr) {
|
||||
if (const char *str = thisValBytes.encode(cx, thisValStr)) {
|
||||
buf = JS_sprintf_append(buf, " this = %s\n", str);
|
||||
if (!buf)
|
||||
|
@ -285,13 +285,14 @@ InitExnPrivate(JSContext *cx, HandleObject exnObject, HandleString message,
|
||||
} else {
|
||||
frame.funName = NULL;
|
||||
}
|
||||
const char *cfilename = i.script()->filename;
|
||||
RootedScript script(cx, i.script());
|
||||
const char *cfilename = script->filename;
|
||||
if (!cfilename)
|
||||
cfilename = "";
|
||||
frame.filename = SaveScriptFilename(cx, cfilename);
|
||||
if (!frame.filename)
|
||||
return false;
|
||||
frame.ulineno = PCToLineNumber(i.script(), i.pc());
|
||||
frame.ulineno = PCToLineNumber(script, i.pc());
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,6 +574,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
|
||||
SkipRoot skip(cx, &iter);
|
||||
|
||||
/* Set the 'fileName' property. */
|
||||
RootedScript script(cx, iter.script());
|
||||
RootedString filename(cx);
|
||||
if (args.length() > 1) {
|
||||
filename = ToString(cx, args[1]);
|
||||
@ -582,7 +584,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
|
||||
} else {
|
||||
filename = cx->runtime->emptyString;
|
||||
if (!iter.done()) {
|
||||
if (const char *cfilename = iter.script()->filename) {
|
||||
if (const char *cfilename = script->filename) {
|
||||
filename = FilenameToString(cx, cfilename);
|
||||
if (!filename)
|
||||
return false;
|
||||
@ -596,7 +598,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
|
||||
if (!ToUint32(cx, args[2], &lineno))
|
||||
return false;
|
||||
} else {
|
||||
lineno = iter.done() ? 0 : PCToLineNumber(iter.script(), iter.pc(), &column);
|
||||
lineno = iter.done() ? 0 : PCToLineNumber(script, iter.pc(), &column);
|
||||
}
|
||||
|
||||
int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32();
|
||||
|
@ -124,6 +124,8 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
|
||||
return false;
|
||||
|
||||
#ifdef JS_ION
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
// If this script hasn't been compiled yet, make sure it will never
|
||||
// be compiled. IonMonkey does not guarantee |f.arguments| can be
|
||||
// fully recovered, so we try to mitigate observing this behavior by
|
||||
@ -421,7 +423,8 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, fun))
|
||||
return false;
|
||||
JS_ASSERT(fun->nargs == fun->script()->bindings.numArgs());
|
||||
js_CallNewScriptHook(cx, fun->script(), fun);
|
||||
RootedScript script(cx, fun->script());
|
||||
js_CallNewScriptHook(cx, script, fun);
|
||||
objp.set(fun);
|
||||
}
|
||||
|
||||
@ -437,6 +440,8 @@ js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, M
|
||||
JSObject *
|
||||
js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
/* NB: Keep this in sync with XDRInterpretedFunction. */
|
||||
|
||||
RootedObject parent(cx, NULL);
|
||||
@ -449,7 +454,8 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF
|
||||
if (!JSObject::clearType(cx, clone))
|
||||
return NULL;
|
||||
|
||||
RawScript clonedScript = CloneScript(cx, enclosingScope, clone, srcFun->script());
|
||||
RootedScript srcScript(cx, srcFun->script());
|
||||
RawScript clonedScript = CloneScript(cx, enclosingScope, clone, srcScript);
|
||||
if (!clonedScript)
|
||||
return NULL;
|
||||
|
||||
@ -461,7 +467,8 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, clone))
|
||||
return NULL;
|
||||
|
||||
js_CallNewScriptHook(cx, clone->script(), clone);
|
||||
RootedScript cloneScript(cx, clone->script());
|
||||
js_CallNewScriptHook(cx, cloneScript, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@ -638,7 +645,7 @@ js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lamb
|
||||
}
|
||||
if (haveSource) {
|
||||
RootedScript script(cx, fun->script());
|
||||
RootedString srcStr(cx, fun->script()->sourceData(cx));
|
||||
RootedString srcStr(cx, script->sourceData(cx));
|
||||
if (!srcStr)
|
||||
return NULL;
|
||||
Rooted<JSStableString *> src(cx, srcStr->ensureStable(cx));
|
||||
@ -1098,7 +1105,9 @@ CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
fun_isGenerator(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
JSFunction *fun;
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
RawFunction fun;
|
||||
if (!IsFunctionObject(vp[1], &fun)) {
|
||||
JS_SET_RVAL(cx, vp, BooleanValue(false));
|
||||
return true;
|
||||
@ -1462,6 +1471,7 @@ JSFunction * JS_FASTCALL
|
||||
js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
HandleObject proto, gc::AllocKind kind)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(parent);
|
||||
JS_ASSERT(proto);
|
||||
JS_ASSERT(!fun->isBoundFunction());
|
||||
@ -1475,7 +1485,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
clone->nargs = fun->nargs;
|
||||
clone->flags = fun->flags & ~JSFUN_EXTENDED;
|
||||
if (fun->isInterpreted()) {
|
||||
clone->initScript(fun->script());
|
||||
clone->initScript(fun->script().unsafeGet());
|
||||
clone->initEnvironment(parent);
|
||||
} else {
|
||||
clone->initNative(fun->native(), fun->jitInfo());
|
||||
@ -1527,8 +1537,9 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
|
||||
GlobalObject *global = script->compileAndGo ? &script->global() : NULL;
|
||||
|
||||
js_CallNewScriptHook(cx, clone->script(), clone);
|
||||
Debugger::onNewScript(cx, clone->script(), global);
|
||||
script = clone->script();
|
||||
js_CallNewScriptHook(cx, script, clone);
|
||||
Debugger::onNewScript(cx, script, global);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
|
@ -132,7 +132,7 @@ struct JSFunction : public JSObject
|
||||
static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
|
||||
static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
|
||||
|
||||
JS::HandleScript script() const {
|
||||
js::Return<JSScript*> script() const {
|
||||
JS_ASSERT(isInterpreted());
|
||||
return JS::HandleScript::fromMarkedLocation(&u.i.script_);
|
||||
}
|
||||
@ -145,7 +145,7 @@ struct JSFunction : public JSObject
|
||||
inline void setScript(JSScript *script_);
|
||||
inline void initScript(JSScript *script_);
|
||||
|
||||
JS::HandleScript maybeScript() const {
|
||||
js::Return<JSScript*> maybeScript() const {
|
||||
return isInterpreted() ? script() : JS::NullPtr();
|
||||
}
|
||||
|
||||
|
@ -4494,15 +4494,14 @@ BudgetIncrementalGC(JSRuntime *rt, int64_t *budget)
|
||||
static JS_NEVER_INLINE void
|
||||
GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gckind, gcreason::Reason reason)
|
||||
{
|
||||
/* If we attempt to invoke the GC while we are running in the GC, assert. */
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next())
|
||||
JS_ASSERT_IF(rt->gcMode == JSGC_MODE_GLOBAL, c->isGCScheduled());
|
||||
#endif
|
||||
|
||||
/* Recursive GC is no-op. */
|
||||
if (rt->isHeapBusy())
|
||||
return;
|
||||
|
||||
/* Don't GC if we are reporting an OOM. */
|
||||
if (rt->inOOMReport)
|
||||
return;
|
||||
|
@ -1233,6 +1233,7 @@ TypeConstraintSetElement::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
void
|
||||
TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
{
|
||||
AssertCanGC();
|
||||
RootedScript script(cx, callsite->script);
|
||||
jsbytecode *pc = callsite->pc;
|
||||
|
||||
@ -1321,7 +1322,8 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!callee->script()->ensureHasTypes(cx))
|
||||
RootedScript calleeScript(cx, callee->script());
|
||||
if (!calleeScript->ensureHasTypes(cx))
|
||||
return;
|
||||
|
||||
unsigned nargs = callee->nargs;
|
||||
@ -1329,18 +1331,18 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
/* Add bindings for the arguments of the call. */
|
||||
for (unsigned i = 0; i < callsite->argumentCount && i < nargs; i++) {
|
||||
StackTypeSet *argTypes = callsite->argumentTypes[i];
|
||||
StackTypeSet *types = TypeScript::ArgTypes(callee->script(), i);
|
||||
StackTypeSet *types = TypeScript::ArgTypes(calleeScript, i);
|
||||
argTypes->addSubsetBarrier(cx, script, pc, types);
|
||||
}
|
||||
|
||||
/* Add void type for any formals in the callee not supplied at the call site. */
|
||||
for (unsigned i = callsite->argumentCount; i < nargs; i++) {
|
||||
TypeSet *types = TypeScript::ArgTypes(callee->script(), i);
|
||||
TypeSet *types = TypeScript::ArgTypes(calleeScript, i);
|
||||
types->addType(cx, Type::UndefinedType());
|
||||
}
|
||||
|
||||
StackTypeSet *thisTypes = TypeScript::ThisTypes(callee->script());
|
||||
HeapTypeSet *returnTypes = TypeScript::ReturnTypes(callee->script());
|
||||
StackTypeSet *thisTypes = TypeScript::ThisTypes(calleeScript);
|
||||
HeapTypeSet *returnTypes = TypeScript::ReturnTypes(calleeScript);
|
||||
|
||||
if (callsite->isNew) {
|
||||
/*
|
||||
@ -1400,7 +1402,7 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
if (!callee->script()->ensureHasTypes(cx))
|
||||
return;
|
||||
|
||||
TypeSet *thisTypes = TypeScript::ThisTypes(callee->script());
|
||||
TypeSet *thisTypes = TypeScript::ThisTypes(callee->script().unsafeGet());
|
||||
if (this->types)
|
||||
this->types->addSubset(cx, thisTypes);
|
||||
else
|
||||
@ -1702,6 +1704,8 @@ HeapTypeSet::HasObjectFlags(JSContext *cx, TypeObject *object, TypeObjectFlags f
|
||||
static inline void
|
||||
ObjectStateChange(JSContext *cx, TypeObject *object, bool markingUnknown, bool force)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (object->unknownProperties())
|
||||
return;
|
||||
|
||||
@ -2538,6 +2542,7 @@ TypeCompartment::addPendingRecompile(JSContext *cx, const RecompileInfo &info)
|
||||
void
|
||||
TypeCompartment::addPendingRecompile(JSContext *cx, HandleScript script, jsbytecode *pc)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(script);
|
||||
if (!constrainedOutputs)
|
||||
return;
|
||||
@ -2577,6 +2582,8 @@ void
|
||||
TypeCompartment::monitorBytecode(JSContext *cx, HandleScript script, uint32_t offset,
|
||||
bool returnOnly)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (!script->ensureRanInference(cx))
|
||||
return;
|
||||
|
||||
@ -5576,7 +5583,7 @@ JSScript::makeAnalysis(JSContext *cx)
|
||||
/* static */ bool
|
||||
JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool singleton)
|
||||
{
|
||||
JS_ASSERT(fun->script());
|
||||
JS_ASSERT(fun->script().unsafeGet());
|
||||
JS_ASSERT(fun->script()->function() == fun);
|
||||
|
||||
if (!cx->typeInferenceEnabled())
|
||||
|
@ -655,6 +655,8 @@ UseNewTypeAtEntry(JSContext *cx, StackFrame *fp)
|
||||
inline bool
|
||||
UseNewTypeForClone(JSFunction *fun)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (fun->hasSingletonType() || !fun->isInterpreted())
|
||||
return false;
|
||||
|
||||
@ -877,6 +879,7 @@ TypeScript::MonitorUnknown(JSContext *cx, HandleScript script, jsbytecode *pc)
|
||||
/* static */ inline void
|
||||
TypeScript::GetPcScript(JSContext *cx, MutableHandleScript script, jsbytecode **pc)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
#ifdef JS_ION
|
||||
if (cx->fp()->beginsIonActivation()) {
|
||||
ion::GetPcScript(cx, script, pc);
|
||||
|
@ -291,7 +291,7 @@ js::RunScript(JSContext *cx, HandleScript script, StackFrame *fp)
|
||||
#endif
|
||||
|
||||
SPSEntryMarker marker(cx->runtime);
|
||||
|
||||
|
||||
#ifdef JS_ION
|
||||
if (ion::IsEnabled(cx)) {
|
||||
ion::MethodStatus status = ion::CanEnter(cx, script, fp, false);
|
||||
@ -299,7 +299,7 @@ js::RunScript(JSContext *cx, HandleScript script, StackFrame *fp)
|
||||
return false;
|
||||
if (status == ion::Method_Compiled) {
|
||||
ion::IonExecStatus status = ion::Cannon(cx, fp);
|
||||
|
||||
|
||||
// Note that if we bailed out, new inline frames may have been
|
||||
// pushed, so we interpret with the current fp.
|
||||
if (status == ion::IonExec_Bailout)
|
||||
@ -375,7 +375,8 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
|
||||
return false;
|
||||
|
||||
/* Run function until JSOP_STOP, JSOP_RETURN or error. */
|
||||
JSBool ok = RunScript(cx, fun->script(), ifg.fp());
|
||||
RootedScript script(cx, fun->script());
|
||||
JSBool ok = RunScript(cx, script, ifg.fp());
|
||||
|
||||
/* Propagate the return value out. */
|
||||
args.rval().set(ifg.fp()->returnValue());
|
||||
@ -791,7 +792,6 @@ js::UnwindScope(JSContext *cx, uint32_t stackDepth)
|
||||
void
|
||||
js::UnwindForUncatchableException(JSContext *cx, const FrameRegs ®s)
|
||||
{
|
||||
|
||||
/* c.f. the regular (catchable) TryNoteIter loop in Interpret. */
|
||||
for (TryNoteIter tni(regs); !tni.done(); ++tni) {
|
||||
JSTryNote *tn = *tni;
|
||||
@ -804,7 +804,7 @@ js::UnwindForUncatchableException(JSContext *cx, const FrameRegs ®s)
|
||||
|
||||
TryNoteIter::TryNoteIter(const FrameRegs ®s)
|
||||
: regs(regs),
|
||||
script(regs.fp()->script()),
|
||||
script(regs.fp()->script().unsafeGet()),
|
||||
pcOffset(regs.pc - script->main())
|
||||
{
|
||||
if (script->hasTrynotes()) {
|
||||
@ -1133,11 +1133,13 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
||||
|
||||
#define SET_SCRIPT(s) \
|
||||
JS_BEGIN_MACRO \
|
||||
EnterAssertNoGCScope(); \
|
||||
script = (s); \
|
||||
if (script->hasAnyBreakpointsOrStepMode() || script->hasScriptCounts) \
|
||||
interrupts.enable(); \
|
||||
JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP, \
|
||||
script->hasAnyBreakpointsOrStepMode()); \
|
||||
LeaveAssertNoGCScope(); \
|
||||
JS_END_MACRO
|
||||
|
||||
/* Repoint cx->regs to a local variable for faster access. */
|
||||
@ -1152,7 +1154,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
||||
|
||||
/* Copy in hot values that change infrequently. */
|
||||
JSRuntime *const rt = cx->runtime;
|
||||
Rooted<JSScript*> script(cx);
|
||||
RootedScript script(cx);
|
||||
SET_SCRIPT(regs.fp()->script());
|
||||
|
||||
/* Reset the loop count on the script we're entering. */
|
||||
@ -2382,9 +2384,8 @@ BEGIN_CASE(JSOP_FUNCALL)
|
||||
|
||||
InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
|
||||
bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
|
||||
JSScript *newScript = fun->script();
|
||||
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, newScript, initial))
|
||||
RawScript funScript = fun->script().unsafeGet();
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial))
|
||||
goto error;
|
||||
|
||||
SET_SCRIPT(regs.fp()->script());
|
||||
|
@ -112,6 +112,7 @@ ComputeThis(JSContext *cx, StackFrame *fp)
|
||||
static inline bool
|
||||
IsOptimizedArguments(StackFrame *fp, Value *vp)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (vp->isMagic(JS_OPTIMIZED_ARGUMENTS) && fp->script()->needsArgsObj())
|
||||
*vp = ObjectValue(fp->argsObj());
|
||||
return vp->isMagic(JS_OPTIMIZED_ARGUMENTS);
|
||||
@ -125,11 +126,13 @@ IsOptimizedArguments(StackFrame *fp, Value *vp)
|
||||
static inline bool
|
||||
GuardFunApplyArgumentsOptimization(JSContext *cx)
|
||||
{
|
||||
AssertCanGC();
|
||||
FrameRegs ®s = cx->regs();
|
||||
if (IsOptimizedArguments(regs.fp(), ®s.sp[-1])) {
|
||||
CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
if (!IsNativeFunction(args.calleev(), js_fun_apply)) {
|
||||
if (!JSScript::argumentsOptimizationFailed(cx, regs.fp()->script()))
|
||||
RootedScript script(cx, regs.fp()->script());
|
||||
if (!JSScript::argumentsOptimizationFailed(cx, script))
|
||||
return false;
|
||||
regs.sp[-1] = ObjectValue(regs.fp()->argsObj());
|
||||
}
|
||||
@ -507,7 +510,7 @@ DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn
|
||||
inline void
|
||||
InterpreterFrames::enableInterruptsIfRunning(JSScript *script)
|
||||
{
|
||||
if (script == regs->fp()->script())
|
||||
if (regs->fp()->script() == script)
|
||||
enabler.enable();
|
||||
}
|
||||
|
||||
@ -758,6 +761,7 @@ static JS_ALWAYS_INLINE bool
|
||||
GetElementOperation(JSContext *cx, JSOp op, HandleValue lref, HandleValue rref,
|
||||
MutableHandleValue res)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM);
|
||||
|
||||
if (lref.isString() && rref.isInt32()) {
|
||||
@ -783,7 +787,8 @@ GetElementOperation(JSContext *cx, JSOp op, HandleValue lref, HandleValue rref,
|
||||
}
|
||||
}
|
||||
|
||||
if (!JSScript::argumentsOptimizationFailed(cx, fp->script()))
|
||||
RootedScript script(cx, fp->script());
|
||||
if (!JSScript::argumentsOptimizationFailed(cx, script))
|
||||
return false;
|
||||
|
||||
lval = ObjectValue(fp->argsObj());
|
||||
|
@ -1503,6 +1503,8 @@ static JSBool
|
||||
SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
|
||||
JSGenerator *gen, const Value &arg)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
if (gen->state == JSGEN_RUNNING || gen->state == JSGEN_CLOSING) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NESTING_GENERATOR);
|
||||
return JS_FALSE;
|
||||
@ -1562,7 +1564,8 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
|
||||
PropertyIteratorObject *enumerators = cx->enumerators;
|
||||
cx->enumerators = gen->enumerators;
|
||||
|
||||
ok = RunScript(cx, fp->script(), fp);
|
||||
RootedScript script(cx, fp->script());
|
||||
ok = RunScript(cx, script, fp);
|
||||
|
||||
gen->enumerators = cx->enumerators;
|
||||
cx->enumerators = enumerators;
|
||||
|
@ -5540,6 +5540,7 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpBacktrace(JSContext *cx)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
Sprinter sprinter(cx);
|
||||
sprinter.init();
|
||||
size_t depth = 0;
|
||||
@ -5547,10 +5548,10 @@ js_DumpBacktrace(JSContext *cx)
|
||||
if (i.isScript()) {
|
||||
const char *filename = JS_GetScriptFilename(cx, i.script());
|
||||
unsigned line = JS_PCToLineNumber(cx, i.script(), i.pc());
|
||||
RawScript script = i.script();
|
||||
sprinter.printf("#%d %14p %s:%d (%p @ %d)\n",
|
||||
depth, (i.isIon() ? 0 : i.interpFrame()),
|
||||
filename, line,
|
||||
i.script(), i.pc() - i.script()->code);
|
||||
depth, (i.isIon() ? 0 : i.interpFrame()), filename, line,
|
||||
script, i.pc() - script->code);
|
||||
} else {
|
||||
sprinter.printf("#%d ???\n", depth);
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ js_DumpPC(JSContext *cx)
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
return JS_FALSE;
|
||||
JSBool ok = js_DisassembleAtPC(cx, cx->fp()->script(), true, cx->regs().pc, &sprinter);
|
||||
JSBool ok = js_DisassembleAtPC(cx, cx->fp()->script().unsafeGet(), true, cx->regs().pc, &sprinter);
|
||||
fprintf(stdout, "%s", sprinter.string());
|
||||
return ok;
|
||||
}
|
||||
@ -1108,7 +1108,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
|
||||
jp->localNames = NULL;
|
||||
jp->decompiledOpcodes = NULL;
|
||||
if (fun && fun->isInterpreted()) {
|
||||
if (!SetPrinterLocalNames(cx, fun->script(), jp)) {
|
||||
if (!SetPrinterLocalNames(cx, fun->script().unsafeGet(), jp)) {
|
||||
js_DestroyPrinter(jp);
|
||||
return NULL;
|
||||
}
|
||||
@ -1764,7 +1764,7 @@ GetArgOrVarAtom(JSPrinter *jp, unsigned slot)
|
||||
{
|
||||
LOCAL_ASSERT_RV(jp->fun, NULL);
|
||||
LOCAL_ASSERT_RV(slot < jp->script->bindings.count(), NULL);
|
||||
LOCAL_ASSERT_RV(jp->script == jp->fun->script(), NULL);
|
||||
LOCAL_ASSERT_RV(jp->script == jp->fun->script().unsafeGet(), NULL);
|
||||
JSAtom *name = (*jp->localNames)[slot].name();
|
||||
#if !JS_HAS_DESTRUCTURING
|
||||
LOCAL_ASSERT_RV(name, NULL);
|
||||
@ -4705,10 +4705,10 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
|
||||
*/
|
||||
LifoAllocScope las(&cx->tempLifoAlloc());
|
||||
outerLocalNames = jp->localNames;
|
||||
if (!SetPrinterLocalNames(cx, fun->script(), jp))
|
||||
if (!SetPrinterLocalNames(cx, fun->script().unsafeGet(), jp))
|
||||
return NULL;
|
||||
|
||||
inner = fun->script();
|
||||
inner = fun->script().unsafeGet();
|
||||
if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner))) {
|
||||
js_delete(jp->localNames);
|
||||
jp->localNames = outerLocalNames;
|
||||
@ -5579,7 +5579,7 @@ js_DecompileFunctionBody(JSPrinter *jp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
script = jp->fun->script();
|
||||
script = jp->fun->script().unsafeGet();
|
||||
return DecompileBody(jp, script, script->code);
|
||||
}
|
||||
|
||||
@ -6133,7 +6133,7 @@ FindStartPC(JSContext *cx, ScriptFrameIter &iter, int spindex, int skipStackHits
|
||||
*valuepc = NULL;
|
||||
|
||||
PCStack pcstack;
|
||||
if (!pcstack.init(cx, iter.script(), current))
|
||||
if (!pcstack.init(cx, iter.script().unsafeGet(), current))
|
||||
return false;
|
||||
|
||||
if (spindex == JSDVG_SEARCH_STACK) {
|
||||
@ -6160,6 +6160,7 @@ FindStartPC(JSContext *cx, ScriptFrameIter &iter, int spindex, int skipStackHits
|
||||
static bool
|
||||
DecompileExpressionFromStack(JSContext *cx, int spindex, int skipStackHits, Value v, char **res)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(spindex < 0 ||
|
||||
spindex == JSDVG_IGNORE_STACK ||
|
||||
spindex == JSDVG_SEARCH_STACK);
|
||||
@ -6180,11 +6181,11 @@ DecompileExpressionFromStack(JSContext *cx, int spindex, int skipStackHits, Valu
|
||||
if (frameIter.done())
|
||||
return true;
|
||||
|
||||
JSScript *script = frameIter.script();
|
||||
RootedScript script(cx, frameIter.script());
|
||||
jsbytecode *valuepc = frameIter.pc();
|
||||
JSFunction *fun = frameIter.isFunctionFrame()
|
||||
? frameIter.callee()
|
||||
: NULL;
|
||||
RootedFunction fun(cx, frameIter.isFunctionFrame()
|
||||
? frameIter.callee()
|
||||
: NULL);
|
||||
|
||||
JS_ASSERT(script->code <= valuepc && valuepc < script->code + script->length);
|
||||
|
||||
@ -6210,6 +6211,7 @@ char *
|
||||
js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
|
||||
HandleString fallbackArg, int skipStackHits)
|
||||
{
|
||||
AssertCanGC();
|
||||
RootedString fallback(cx, fallbackArg);
|
||||
{
|
||||
char *result;
|
||||
|
@ -413,7 +413,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
uint32_t scriptBits = 0;
|
||||
|
||||
JSContext *cx = xdr->cx();
|
||||
Rooted<JSScript*> script(cx);
|
||||
RootedScript script(cx);
|
||||
nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = 0;
|
||||
jssrcnote *notes = NULL;
|
||||
|
||||
@ -1773,6 +1773,8 @@ JSScript::isShortRunning()
|
||||
bool
|
||||
JSScript::enclosingScriptsCompiledSuccessfully() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* When a nested script is succesfully compiled, it is eagerly given the
|
||||
* static JSFunction of its enclosing script. The enclosing function's
|
||||
@ -2051,6 +2053,7 @@ namespace js {
|
||||
unsigned
|
||||
CurrentLine(JSContext *cx)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
return PCToLineNumber(cx->fp()->script(), cx->regs().pc);
|
||||
}
|
||||
|
||||
@ -2058,6 +2061,7 @@ void
|
||||
CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *linenop,
|
||||
JSPrincipals **origin)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
NonBuiltinScriptFrameIter iter(cx);
|
||||
|
||||
if (iter.done()) {
|
||||
@ -2067,7 +2071,7 @@ CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *line
|
||||
return;
|
||||
}
|
||||
|
||||
RootedScript script(cx, iter.script());
|
||||
RawScript script = iter.script();
|
||||
*file = script->filename;
|
||||
*linenop = PCToLineNumber(iter.script(), iter.pc());
|
||||
*origin = script->originPrincipals;
|
||||
@ -2086,6 +2090,8 @@ Rebase(RawScript dst, RawScript src, T *srcp)
|
||||
JSScript *
|
||||
js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript src)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
/* NB: Keep this in sync with XDRScript. */
|
||||
|
||||
uint32_t nconsts = src->hasConsts() ? src->consts()->length : 0;
|
||||
@ -2549,6 +2555,7 @@ JSScript::setNeedsArgsObj(bool needsArgsObj)
|
||||
/* static */ bool
|
||||
JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(script->analyzedArgsUsage());
|
||||
JS_ASSERT(script->argumentsHasVarBinding());
|
||||
JS_ASSERT(!script->isGenerator);
|
||||
|
@ -45,9 +45,10 @@ CurrentScriptFileLineOrigin(JSContext *cx, const char **file, unsigned *linenop,
|
||||
LineOption opt = NOT_CALLED_FROM_JSOP_EVAL)
|
||||
{
|
||||
if (opt == CALLED_FROM_JSOP_EVAL) {
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(JSOp(*cx->regs().pc) == JSOP_EVAL);
|
||||
JS_ASSERT(*(cx->regs().pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
|
||||
JSScript *script = cx->fp()->script();
|
||||
RawScript script = cx->fp()->script();
|
||||
*file = script->filename;
|
||||
*linenop = GET_UINT16(cx->regs().pc + JSOP_EVAL_LENGTH);
|
||||
*origin = script->originPrincipals;
|
||||
|
@ -2360,6 +2360,8 @@ static const uint32_t ReplaceOptArg = 2;
|
||||
static JSObject *
|
||||
LambdaIsGetElem(JSObject &lambda)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (!lambda.isFunction())
|
||||
return NULL;
|
||||
|
||||
@ -2367,7 +2369,7 @@ LambdaIsGetElem(JSObject &lambda)
|
||||
if (!fun->isInterpreted())
|
||||
return NULL;
|
||||
|
||||
JSScript *script = fun->script();
|
||||
RawScript script = fun->script();
|
||||
jsbytecode *pc = script->code;
|
||||
|
||||
/*
|
||||
|
@ -1753,7 +1753,8 @@ ParseXMLSource(JSContext *cx, HandleString src)
|
||||
op = (JSOp) *i.pc();
|
||||
if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) {
|
||||
filename = i.script()->filename;
|
||||
lineno = PCToLineNumber(i.script(), i.pc());
|
||||
RootedScript script(cx, i.script());
|
||||
lineno = PCToLineNumber(script, i.pc());
|
||||
for (endp = srcp + srclen; srcp < endp; srcp++) {
|
||||
if (*srcp == '\n')
|
||||
--lineno;
|
||||
|
@ -143,6 +143,7 @@ class Assembler : public ValueAssembler
|
||||
vmframe(vmframe),
|
||||
pc(NULL)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
startLabel = label();
|
||||
if (vmframe)
|
||||
sps->setPushed(vmframe->script());
|
||||
|
@ -135,6 +135,7 @@ class LinkerHelper : public JSC::LinkBuffer
|
||||
}
|
||||
|
||||
JSC::CodeLocationLabel finalize(VMFrame &f) {
|
||||
AutoAssertNoGC nogc;
|
||||
masm.finalize(*this);
|
||||
JSC::CodeLocationLabel label = finalizeCodeAddendum();
|
||||
Probes::registerICCode(f.cx, f.chunk(), f.script(), f.pc(),
|
||||
|
@ -48,7 +48,7 @@ static jsbytecode *
|
||||
FindExceptionHandler(JSContext *cx)
|
||||
{
|
||||
StackFrame *fp = cx->fp();
|
||||
JSScript *script = fp->script();
|
||||
RootedScript script(cx, fp->script());
|
||||
|
||||
if (!script->hasTrynotes())
|
||||
return NULL;
|
||||
@ -185,6 +185,7 @@ stubs::HitStackQuota(VMFrame &f)
|
||||
void * JS_FASTCALL
|
||||
stubs::FixupArity(VMFrame &f, uint32_t nactual)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = f.cx;
|
||||
StackFrame *oldfp = f.fp();
|
||||
|
||||
@ -196,9 +197,9 @@ stubs::FixupArity(VMFrame &f, uint32_t nactual)
|
||||
* members that have been initialized by the caller and early prologue.
|
||||
*/
|
||||
InitialFrameFlags initial = oldfp->initialFlags();
|
||||
JSFunction *fun = oldfp->fun();
|
||||
JSScript *script = fun->script();
|
||||
void *ncode = oldfp->nativeReturnAddress();
|
||||
RootedFunction fun(cx, oldfp->fun());
|
||||
RootedScript script(cx, fun->script());
|
||||
void *ncode = oldfp->nativeReturnAddress();
|
||||
|
||||
/* Pop the inline frame. */
|
||||
f.regs.popPartialFrame((Value *)oldfp);
|
||||
@ -277,10 +278,11 @@ static inline bool
|
||||
UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
|
||||
void **pret, bool *unjittable, uint32_t argc)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = f.cx;
|
||||
CallArgs args = CallArgsFromSp(argc, f.regs.sp);
|
||||
JSFunction *newfun = args.callee().toFunction();
|
||||
JSScript *newscript = newfun->script();
|
||||
RootedFunction newfun(cx, args.callee().toFunction());
|
||||
RootedScript newscript(cx, newfun->script());
|
||||
|
||||
bool construct = InitialFrameFlagsAreConstructing(initial);
|
||||
|
||||
@ -292,7 +294,7 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
|
||||
return false;
|
||||
|
||||
/* Try to compile if not already compiled. */
|
||||
if (ShouldJaegerCompileCallee(cx, f.script(), newscript, f.jit())) {
|
||||
if (ShouldJaegerCompileCallee(cx, f.script().unsafeGet(), newscript, f.jit())) {
|
||||
CompileStatus status = CanMethodJIT(cx, newscript, newscript->code, construct,
|
||||
CompileRequest_JIT, f.fp());
|
||||
if (status == Compile_Error) {
|
||||
@ -521,7 +523,8 @@ js_InternalThrow(VMFrame &f)
|
||||
Value rval;
|
||||
JSTrapStatus st = Debugger::onExceptionUnwind(cx, &rval);
|
||||
if (st == JSTRAP_CONTINUE && handler) {
|
||||
st = handler(cx, cx->fp()->script(), cx->regs().pc, &rval,
|
||||
RootedScript fscript(cx, cx->fp()->script());
|
||||
st = handler(cx, fscript, cx->regs().pc, &rval,
|
||||
cx->runtime->debugHooks.throwHookData);
|
||||
}
|
||||
|
||||
@ -594,7 +597,7 @@ js_InternalThrow(VMFrame &f)
|
||||
return NULL;
|
||||
|
||||
StackFrame *fp = cx->fp();
|
||||
JSScript *script = fp->script();
|
||||
RootedScript script(cx, fp->script());
|
||||
|
||||
/*
|
||||
* Fall back to EnterMethodJIT and finish the frame in the interpreter.
|
||||
@ -654,7 +657,8 @@ stubs::CreateThis(VMFrame &f, JSObject *proto)
|
||||
void JS_FASTCALL
|
||||
stubs::ScriptDebugPrologue(VMFrame &f)
|
||||
{
|
||||
Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
|
||||
AssertCanGC();
|
||||
Probes::enterScript(f.cx, f.script().unsafeGet(), f.script()->function(), f.fp());
|
||||
JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
|
||||
switch (status) {
|
||||
case JSTRAP_CONTINUE:
|
||||
@ -680,28 +684,32 @@ stubs::ScriptDebugEpilogue(VMFrame &f)
|
||||
void JS_FASTCALL
|
||||
stubs::ScriptProbeOnlyPrologue(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::ScriptProbeOnlyEpilogue(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
Probes::exitScript(f.cx, f.script(), f.script()->function(), f.fp());
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::CrossChunkShim(VMFrame &f, void *edge_)
|
||||
{
|
||||
AssertCanGC();
|
||||
DebugOnly<CrossChunkEdge*> edge = (CrossChunkEdge *) edge_;
|
||||
|
||||
mjit::ExpandInlineFrames(f.cx->compartment);
|
||||
|
||||
JSScript *script = f.script();
|
||||
RawScript script = f.script().unsafeGet();
|
||||
JS_ASSERT(edge->target < script->length);
|
||||
JS_ASSERT(script->code + edge->target == f.pc());
|
||||
|
||||
CompileStatus status = CanMethodJIT(f.cx, script, f.pc(), f.fp()->isConstructing(),
|
||||
CompileRequest_Interpreter, f.fp());
|
||||
script = NULL;
|
||||
if (status == Compile_Error)
|
||||
THROW();
|
||||
|
||||
@ -916,7 +924,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
|
||||
}
|
||||
|
||||
case REJOIN_THIS_CREATED: {
|
||||
Probes::enterScript(f.cx, f.script(), f.script()->function(), fp);
|
||||
Probes::enterScript(f.cx, f.script().unsafeGet(), f.script()->function(), fp);
|
||||
|
||||
if (script->debugMode) {
|
||||
JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
|
||||
@ -976,7 +984,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case REJOIN_EVAL_PROLOGUE:
|
||||
Probes::enterScript(cx, f.script(), f.script()->function(), fp);
|
||||
Probes::enterScript(cx, f.script().unsafeGet(), f.script()->function(), fp);
|
||||
if (cx->compartment->debugMode()) {
|
||||
JSTrapStatus status = ScriptDebugPrologue(cx, fp);
|
||||
switch (status) {
|
||||
|
@ -1021,11 +1021,9 @@ JaegerStatus
|
||||
mjit::EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimit, bool partial)
|
||||
{
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
Profiler prof;
|
||||
JSScript *script = fp->script();
|
||||
|
||||
JaegerSpew(JSpew_Prof, "%s jaeger script, line %d\n",
|
||||
script->filename, script->lineno);
|
||||
fp->script()->filename, fp->script()->lineno);
|
||||
Profiler prof;
|
||||
prof.start();
|
||||
#endif
|
||||
|
||||
@ -1107,16 +1105,15 @@ JaegerStatus
|
||||
mjit::JaegerShot(JSContext *cx, bool partial)
|
||||
{
|
||||
StackFrame *fp = cx->fp();
|
||||
JSScript *script = fp->script();
|
||||
JITScript *jit = script->getJIT(fp->isConstructing(), cx->compartment->compileBarriers());
|
||||
JITScript *jit = fp->script()->getJIT(fp->isConstructing(), cx->compartment->compileBarriers());
|
||||
|
||||
JS_ASSERT(cx->regs().pc == script->code);
|
||||
JS_ASSERT(cx->regs().pc == fp->script()->code);
|
||||
|
||||
#if JS_TRACE_LOGGING
|
||||
AutoTraceLog logger(TraceLogging::defaultLogger(),
|
||||
TraceLogging::JM_START,
|
||||
TraceLogging::JM_STOP,
|
||||
script);
|
||||
fp->script().unsafeGet());
|
||||
#endif
|
||||
|
||||
return CheckStackAndEnterMethodJIT(cx, cx->fp(), jit->invokeEntry, partial);
|
||||
@ -1129,7 +1126,7 @@ js::mjit::JaegerShotAtSafePoint(JSContext *cx, void *safePoint, bool partial)
|
||||
AutoTraceLog logger(TraceLogging::defaultLogger(),
|
||||
TraceLogging::JM_SAFEPOINT_START,
|
||||
TraceLogging::JM_SAFEPOINT_STOP,
|
||||
cx->fp()->script());
|
||||
cx->fp()->script().unsafeGet());
|
||||
#endif
|
||||
return CheckStackAndEnterMethodJIT(cx, cx->fp(), safePoint, partial);
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ struct VMFrame
|
||||
inline unsigned chunkIndex();
|
||||
|
||||
/* Get the inner script/PC in case of inlining. */
|
||||
inline JSScript *script();
|
||||
inline Return<JSScript*> script();
|
||||
inline jsbytecode *pc();
|
||||
|
||||
#if defined(JS_CPU_SPARC)
|
||||
@ -1042,9 +1042,10 @@ VMFrame::chunkIndex()
|
||||
return jit()->chunkIndex(regs.pc);
|
||||
}
|
||||
|
||||
inline JSScript *
|
||||
inline Return<JSScript*>
|
||||
VMFrame::script()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (regs.inlined())
|
||||
return chunk()->inlineFrames()[regs.inlined()->inlineIndex].fun->script();
|
||||
return fp()->script();
|
||||
@ -1053,6 +1054,7 @@ VMFrame::script()
|
||||
inline jsbytecode *
|
||||
VMFrame::pc()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (regs.inlined())
|
||||
return script()->code + regs.inlined()->pcOffset;
|
||||
return regs.pc;
|
||||
|
@ -61,6 +61,8 @@ PatchGetFallback(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
void JS_FASTCALL
|
||||
ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
RootedObject obj(f.cx, &f.fp()->global());
|
||||
PropertyName *name = f.script()->getName(GET_UINT32_INDEX(f.pc()));
|
||||
|
||||
@ -100,7 +102,9 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
static void JS_FASTCALL
|
||||
DisabledSetGlobal(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
{
|
||||
stubs::SetName(f, f.script()->getName(GET_UINT32_INDEX(f.pc())));
|
||||
AssertCanGC();
|
||||
RootedPropertyName name(f.cx, f.script()->getName(GET_UINT32_INDEX(f.pc())));
|
||||
stubs::SetName(f, name);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -151,6 +155,8 @@ UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, Shape *s
|
||||
void JS_FASTCALL
|
||||
ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
RootedObject obj(f.cx, &f.fp()->global());
|
||||
RootedPropertyName name(f.cx, f.script()->getName(GET_UINT32_INDEX(f.pc())));
|
||||
|
||||
@ -418,6 +424,8 @@ mjit::NativeStubEpilogue(VMFrame &f, Assembler &masm, NativeStubLinker::FinalJum
|
||||
int32_t initialFrameDepth, int32_t vpOffset,
|
||||
MaybeRegisterID typeReg, MaybeRegisterID dataReg)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/* Reload fp, which may have been clobbered by restoreStackBase(). */
|
||||
masm.loadPtr(FrameAddress(VMFrame::offsetOfFp), JSFrameReg);
|
||||
|
||||
@ -829,6 +837,8 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
bool generateFullCallStub(JSScript *script, uint32_t flags)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* Create a stub that works with arity mismatches. Like the fast-path,
|
||||
* this allocates a frame on the caller side, but also performs extra
|
||||
@ -974,6 +984,7 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
bool generateStubForClosures(JSObject *obj)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(ic.frameSize.isStatic());
|
||||
|
||||
/* Slightly less fast path - guard on fun->script() instead. */
|
||||
@ -1066,9 +1077,9 @@ class CallCompiler : public BaseCompiler
|
||||
* inlining the parent frame in the first place, so mark the immediate
|
||||
* caller as uninlineable.
|
||||
*/
|
||||
if (f.script()->function()) {
|
||||
f.script()->uninlineable = true;
|
||||
MarkTypeObjectFlags(cx, f.script()->function(), types::OBJECT_FLAG_UNINLINEABLE);
|
||||
if (fscript->function()) {
|
||||
fscript->uninlineable = true;
|
||||
MarkTypeObjectFlags(cx, fscript->function(), types::OBJECT_FLAG_UNINLINEABLE);
|
||||
}
|
||||
|
||||
/* Don't touch the IC if the call triggered a recompilation. */
|
||||
@ -1104,7 +1115,7 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
/* N.B. After this call, the frame will have a dynamic frame size. */
|
||||
if (ic.frameSize.isDynamic()) {
|
||||
masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
|
||||
masm.bumpStubCount(fscript, f.pc(), Registers::tempCallReg());
|
||||
masm.fallibleVMCall(cx->typeInferenceEnabled(),
|
||||
JS_FUNC_TO_DATA_PTR(void *, ic::SplatApplyArgs),
|
||||
f.regs.pc, NULL, initialFrameDepth);
|
||||
@ -1112,7 +1123,7 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
Registers tempRegs = Registers::tempCallRegMask();
|
||||
RegisterID t0 = tempRegs.takeAnyReg().reg();
|
||||
masm.bumpStubCount(f.script(), f.pc(), t0);
|
||||
masm.bumpStubCount(fscript, f.pc(), t0);
|
||||
|
||||
int32_t storeFrameDepth = ic.frameSize.isStatic() ? initialFrameDepth : -1;
|
||||
masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, storeFrameDepth);
|
||||
@ -1229,6 +1240,8 @@ class CallCompiler : public BaseCompiler
|
||||
disable();
|
||||
|
||||
#ifdef JS_ION
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
// If the following conditions pass, try to inline a call into
|
||||
// an IonMonkey JIT'd function.
|
||||
if (!callingNew &&
|
||||
@ -1246,6 +1259,7 @@ class CallCompiler : public BaseCompiler
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(fun);
|
||||
JSScript *script = fun->script();
|
||||
JS_ASSERT(script);
|
||||
@ -1412,6 +1426,7 @@ ic::SplatApplyArgs(VMFrame &f)
|
||||
void
|
||||
ic::GenerateArgumentCheckStub(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(f.cx->typeInferenceEnabled());
|
||||
|
||||
JITScript *jit = f.jit();
|
||||
|
@ -111,6 +111,7 @@ class PICStubCompiler : public BaseCompiler
|
||||
protected:
|
||||
void spew(const char *event, const char *op) {
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
AutoAssertNoGC nogc;
|
||||
JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
|
||||
type, event, op, f.script()->filename, CurrentLine(cx));
|
||||
#endif
|
||||
@ -728,6 +729,7 @@ struct GetPropHelper {
|
||||
}
|
||||
|
||||
LookupStatus testForGet() {
|
||||
AutoAssertNoGC nogc;
|
||||
if (!shape->hasDefaultGetter()) {
|
||||
if (shape->hasGetterValue()) {
|
||||
JSObject *getterObj = shape->getterObject();
|
||||
@ -896,6 +898,8 @@ class GetPropCompiler : public PICStubCompiler
|
||||
|
||||
LookupStatus generateStringPropertyStub()
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
if (!f.fp()->script()->compileAndGo)
|
||||
return disable("String.prototype without compile-and-go global");
|
||||
|
||||
@ -1050,6 +1054,8 @@ class GetPropCompiler : public PICStubCompiler
|
||||
void generateGetterStub(Assembler &masm, Shape *shape, jsid userid,
|
||||
Label start, Vector<Jump, 8> &shapeMismatches)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* Getter hook needs to be called from the stub. The state is fully
|
||||
* synced and no registers are live except the result registers.
|
||||
@ -1160,6 +1166,8 @@ class GetPropCompiler : public PICStubCompiler
|
||||
void generateNativeGetterStub(Assembler &masm, Shape *shape,
|
||||
Label start, Vector<Jump, 8> &shapeMismatches)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* Getter hook needs to be called from the stub. The state is fully
|
||||
* synced and no registers are live except the result registers.
|
||||
@ -1250,6 +1258,7 @@ class GetPropCompiler : public PICStubCompiler
|
||||
|
||||
LookupStatus generateStub(JSObject *holder, HandleShape shape)
|
||||
{
|
||||
AssertCanGC();
|
||||
Vector<Jump, 8> shapeMismatches(cx);
|
||||
|
||||
MJITInstrumentation sps(&f.cx->runtime->spsProfiler);
|
||||
@ -1264,7 +1273,10 @@ class GetPropCompiler : public PICStubCompiler
|
||||
|
||||
bool setStubShapeOffset = true;
|
||||
if (obj->isDenseArray()) {
|
||||
MarkNotIdempotent(f.script(), f.pc());
|
||||
{
|
||||
RawScript script = f.script().unsafeGet();
|
||||
MarkNotIdempotent(script, f.pc());
|
||||
}
|
||||
|
||||
start = masm.label();
|
||||
shapeGuardJump = masm.branchPtr(Assembler::NotEqual,
|
||||
@ -1380,7 +1392,10 @@ class GetPropCompiler : public PICStubCompiler
|
||||
}
|
||||
|
||||
if (shape && !shape->hasDefaultGetter()) {
|
||||
MarkNotIdempotent(f.script(), f.pc());
|
||||
{
|
||||
RawScript script = f.script().unsafeGet();
|
||||
MarkNotIdempotent(script, f.pc());
|
||||
}
|
||||
|
||||
if (shape->hasGetterValue()) {
|
||||
generateNativeGetterStub(masm, shape, start, shapeMismatches);
|
||||
@ -1485,14 +1500,17 @@ class GetPropCompiler : public PICStubCompiler
|
||||
/* Don't touch the IC if it may have been destroyed. */
|
||||
if (!monitor.recompiled())
|
||||
pic.hadUncacheable = true;
|
||||
MarkNotIdempotent(f.script(), f.pc());
|
||||
RawScript script = f.script().unsafeGet();
|
||||
MarkNotIdempotent(script, f.pc());
|
||||
return status;
|
||||
}
|
||||
|
||||
// Mark as not idempotent to avoid recompilation in Ion Monkey
|
||||
// GetPropertyCache.
|
||||
if (!obj->hasIdempotentProtoChain())
|
||||
MarkNotIdempotent(f.script(), f.pc());
|
||||
if (!obj->hasIdempotentProtoChain()) {
|
||||
RawScript script = f.script().unsafeGet();
|
||||
MarkNotIdempotent(script, f.pc());
|
||||
}
|
||||
|
||||
if (hadGC())
|
||||
return Lookup_Uncacheable;
|
||||
@ -2046,7 +2064,8 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
|
||||
|
||||
RootedValue v(f.cx);
|
||||
if (cached) {
|
||||
if (!GetPropertyOperation(f.cx, f.script(), f.pc(), &objval, &v))
|
||||
RootedScript script(f.cx, f.script());
|
||||
if (!GetPropertyOperation(f.cx, script, f.pc(), &objval, &v))
|
||||
THROW();
|
||||
} else {
|
||||
if (!JSObject::getProperty(f.cx, obj, obj, name, &v))
|
||||
@ -2170,6 +2189,7 @@ void
|
||||
BaseIC::spew(VMFrame &f, const char *event, const char *message)
|
||||
{
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
AutoAssertNoGC nogc;
|
||||
JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
|
||||
js_CodeName[JSOp(*f.pc())], event, message,
|
||||
f.cx->fp()->script()->filename, CurrentLine(f.cx));
|
||||
@ -2177,8 +2197,11 @@ BaseIC::spew(VMFrame &f, const char *event, const char *message)
|
||||
}
|
||||
|
||||
/* Total length of scripts preceding a frame. */
|
||||
inline uint32_t frameCountersOffset(VMFrame &f)
|
||||
inline uint32_t
|
||||
frameCountersOffset(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
JSContext *cx = f.cx;
|
||||
|
||||
uint32_t offset = 0;
|
||||
@ -2413,7 +2436,8 @@ GetElementIC::attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandleP
|
||||
char *chars = DeflateString(cx, v.toString()->getChars(cx), v.toString()->length());
|
||||
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom %p (\"%s\") shape %p (%s: %d)\n",
|
||||
js_CodeName[JSOp(*f.pc())], cs.executableAddress(), (void*)name, chars,
|
||||
(void*)holder->lastProperty(), cx->fp()->script()->filename, CurrentLine(cx));
|
||||
(void*)holder->lastProperty(), cx->fp()->script()->filename,
|
||||
CurrentLine(cx));
|
||||
js_free(chars);
|
||||
#endif
|
||||
|
||||
|
@ -136,6 +136,8 @@ Recompiler::patchNative(JSCompartment *compartment, JITChunk *chunk, StackFrame
|
||||
void
|
||||
Recompiler::patchFrame(JSCompartment *compartment, VMFrame *f, JSScript *script)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* Check if the VMFrame returns directly into the script's jitcode. This
|
||||
* depends on the invariant that f->fp() reflects the frame at the point
|
||||
@ -179,6 +181,8 @@ Recompiler::patchFrame(JSCompartment *compartment, VMFrame *f, JSScript *script)
|
||||
StackFrame *
|
||||
Recompiler::expandInlineFrameChain(StackFrame *outer, InlineFrame *inner)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
StackFrame *parent;
|
||||
if (inner->parent)
|
||||
parent = expandInlineFrameChain(outer, inner->parent);
|
||||
@ -223,6 +227,7 @@ Recompiler::expandInlineFrames(JSCompartment *compartment,
|
||||
StackFrame *fp, mjit::CallSite *inlined,
|
||||
StackFrame *next, VMFrame *f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT_IF(next, next->prev() == fp && next->prevInline() == inlined);
|
||||
|
||||
/*
|
||||
@ -328,6 +333,7 @@ ExpandInlineFrames(JSCompartment *compartment)
|
||||
void
|
||||
ClearAllFrames(JSCompartment *compartment)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (!compartment || !compartment->rt->hasJaegerRuntime())
|
||||
return;
|
||||
|
||||
@ -394,6 +400,7 @@ ClearAllFrames(JSCompartment *compartment)
|
||||
void
|
||||
Recompiler::clearStackReferences(FreeOp *fop, JSScript *script)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(script->hasMJITInfo());
|
||||
|
||||
JaegerSpew(JSpew_Recompile, "recompiling script (file \"%s\") (line \"%d\") (length \"%d\") (usecount=\"%d\")\n",
|
||||
|
@ -74,11 +74,13 @@ stubs::BindGlobalName(VMFrame &f)
|
||||
void JS_FASTCALL
|
||||
stubs::SetName(VMFrame &f, PropertyName *name)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSContext *cx = f.cx;
|
||||
RootedObject scope(cx, &f.regs.sp[-2].toObject());
|
||||
HandleValue value = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
|
||||
RootedScript fscript(cx, f.script());
|
||||
|
||||
if (!SetNameOperation(cx, f.script(), f.pc(), scope, value))
|
||||
if (!SetNameOperation(cx, fscript, f.pc(), scope, value))
|
||||
THROW();
|
||||
|
||||
f.regs.sp[-2] = f.regs.sp[-1];
|
||||
@ -117,7 +119,7 @@ stubs::SetElem(VMFrame &f)
|
||||
|
||||
RootedId id(cx);
|
||||
|
||||
Rooted<JSObject*> obj(cx, ToObjectFromStack(cx, objval));
|
||||
RootedObject obj(cx, ToObjectFromStack(cx, objval));
|
||||
if (!obj)
|
||||
THROW();
|
||||
|
||||
@ -286,7 +288,7 @@ stubs::Ursh(VMFrame &f)
|
||||
|
||||
template<JSBool strict>
|
||||
void JS_FASTCALL
|
||||
stubs::DefFun(VMFrame &f, JSFunction *fun_)
|
||||
stubs::DefFun(VMFrame &f, JSFunction *funArg)
|
||||
{
|
||||
/*
|
||||
* A top-level function defined in Global or Eval code (see ECMA-262
|
||||
@ -296,7 +298,7 @@ stubs::DefFun(VMFrame &f, JSFunction *fun_)
|
||||
*/
|
||||
JSContext *cx = f.cx;
|
||||
StackFrame *fp = f.fp();
|
||||
RootedFunction fun(f.cx, fun_);
|
||||
RootedFunction fun(f.cx, funArg);
|
||||
|
||||
/*
|
||||
* If static link is not current scope, clone fun's object to link to the
|
||||
@ -747,14 +749,17 @@ stubs::Mod(VMFrame &f)
|
||||
void JS_FASTCALL
|
||||
stubs::DebuggerStatement(VMFrame &f, jsbytecode *pc)
|
||||
{
|
||||
AssertCanGC();
|
||||
JSDebuggerHandler handler = f.cx->runtime->debugHooks.debuggerHandler;
|
||||
if (handler || !f.cx->compartment->getDebuggees().empty()) {
|
||||
JSTrapStatus st = JSTRAP_CONTINUE;
|
||||
Value rval;
|
||||
if (handler)
|
||||
st = handler(f.cx, f.script(), pc, &rval, f.cx->runtime->debugHooks.debuggerHandlerData);
|
||||
RootedValue rval(f.cx);
|
||||
if (handler) {
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
st = handler(f.cx, fscript, pc, rval.address(), f.cx->runtime->debugHooks.debuggerHandlerData);
|
||||
}
|
||||
if (st == JSTRAP_CONTINUE)
|
||||
st = Debugger::onDebuggerStatement(f.cx, &rval);
|
||||
st = Debugger::onDebuggerStatement(f.cx, rval.address());
|
||||
|
||||
switch (st) {
|
||||
case JSTRAP_THROW:
|
||||
@ -790,7 +795,8 @@ stubs::Interrupt(VMFrame &f, jsbytecode *pc)
|
||||
void JS_FASTCALL
|
||||
stubs::TriggerIonCompile(VMFrame &f)
|
||||
{
|
||||
JSScript *script = f.script();
|
||||
AssertCanGC();
|
||||
RootedScript script(f.cx, f.script());
|
||||
|
||||
if (ion::js_IonOptions.parallelCompilation) {
|
||||
JS_ASSERT(!script->ion);
|
||||
@ -829,6 +835,7 @@ stubs::TriggerIonCompile(VMFrame &f)
|
||||
void JS_FASTCALL
|
||||
stubs::RecompileForInline(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
ExpandInlineFrames(f.cx->compartment);
|
||||
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script());
|
||||
f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
|
||||
@ -851,8 +858,10 @@ stubs::Trap(VMFrame &f, uint32_t trapTypes)
|
||||
* setting the interruptHook to NULL.
|
||||
*/
|
||||
JSInterruptHook hook = f.cx->runtime->debugHooks.interruptHook;
|
||||
if (hook)
|
||||
result = hook(f.cx, f.script(), f.pc(), &rval, f.cx->runtime->debugHooks.interruptHookData);
|
||||
if (hook) {
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
result = hook(f.cx, fscript, f.pc(), &rval, f.cx->runtime->debugHooks.interruptHookData);
|
||||
}
|
||||
|
||||
if (result == JSTRAP_CONTINUE)
|
||||
result = Debugger::onSingleStep(f.cx, &rval);
|
||||
@ -1034,7 +1043,8 @@ stubs::GetProp(VMFrame &f, PropertyName *name)
|
||||
MutableHandleValue objval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
|
||||
|
||||
RootedValue rval(cx);
|
||||
if (!GetPropertyOperation(cx, f.script(), f.pc(), objval, &rval))
|
||||
RootedScript fscript(cx, f.script());
|
||||
if (!GetPropertyOperation(cx, fscript, f.pc(), objval, &rval))
|
||||
THROW();
|
||||
|
||||
regs.sp[-1] = rval;
|
||||
@ -1293,6 +1303,7 @@ FindNativeCode(VMFrame &f, jsbytecode *target)
|
||||
void * JS_FASTCALL
|
||||
stubs::LookupSwitch(VMFrame &f, jsbytecode *pc)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
jsbytecode *jpc = pc;
|
||||
JSScript *script = f.fp()->script();
|
||||
|
||||
@ -1545,12 +1556,12 @@ stubs::TypeBarrierHelper(VMFrame &f, uint32_t which)
|
||||
* script have been destroyed, as we will reanalyze and prune type barriers
|
||||
* as they are regenerated.
|
||||
*/
|
||||
if (f.script()->hasAnalysis() && f.script()->analysis()->ranInference()) {
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
|
||||
AutoEnterTypeInference enter(f.cx);
|
||||
f.script()->analysis()->breakTypeBarriers(f.cx, f.pc() - f.script()->code, false);
|
||||
fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
|
||||
}
|
||||
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
TypeScript::Monitor(f.cx, fscript, f.pc(), result);
|
||||
}
|
||||
|
||||
@ -1559,12 +1570,12 @@ stubs::StubTypeHelper(VMFrame &f, int32_t which)
|
||||
{
|
||||
const Value &result = f.regs.sp[which];
|
||||
|
||||
if (f.script()->hasAnalysis() && f.script()->analysis()->ranInference()) {
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
|
||||
AutoEnterTypeInference enter(f.cx);
|
||||
f.script()->analysis()->breakTypeBarriers(f.cx, f.pc() - f.script()->code, false);
|
||||
fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
|
||||
}
|
||||
|
||||
RootedScript fscript(f.cx, f.script());
|
||||
TypeScript::Monitor(f.cx, fscript, f.pc(), result);
|
||||
}
|
||||
|
||||
@ -1617,9 +1628,10 @@ stubs::CheckArgumentTypes(VMFrame &f)
|
||||
void JS_FASTCALL
|
||||
stubs::AssertArgumentTypes(VMFrame &f)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StackFrame *fp = f.fp();
|
||||
JSFunction *fun = fp->fun();
|
||||
JSScript *script = fun->script();
|
||||
RawScript script = fun->script();
|
||||
|
||||
/*
|
||||
* Don't check the type of 'this' for constructor frames, the 'this' value
|
||||
@ -1649,6 +1661,7 @@ void JS_FASTCALL stubs::MissedBoundsCheckHead(VMFrame &f) {}
|
||||
void * JS_FASTCALL
|
||||
stubs::InvariantFailure(VMFrame &f, void *rval)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
/*
|
||||
* Patch this call to the return site of the call triggering the invariant
|
||||
* failure (or a MissedBoundsCheck* function if the failure occurred on
|
||||
@ -1663,7 +1676,7 @@ stubs::InvariantFailure(VMFrame &f, void *rval)
|
||||
*frameAddr = repatchCode;
|
||||
|
||||
/* Recompile the outermost script, and don't hoist any bounds checks. */
|
||||
JSScript *script = f.fp()->script();
|
||||
RawScript script = f.fp()->script();
|
||||
JS_ASSERT(!script->failedBoundsCheck);
|
||||
script->failedBoundsCheck = true;
|
||||
|
||||
|
@ -1312,11 +1312,11 @@ AssertJit(JSContext *cx, unsigned argc, jsval *vp)
|
||||
static JSScript *
|
||||
ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL)
|
||||
{
|
||||
JSFunction *fun = JS_ValueToFunction(cx, v);
|
||||
RootedFunction fun(cx, JS_ValueToFunction(cx, v));
|
||||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
JSScript *script = fun->maybeScript();
|
||||
RootedScript script(cx, fun->maybeScript());
|
||||
if (!script)
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_SCRIPTS_ONLY);
|
||||
|
||||
@ -1399,7 +1399,7 @@ TrapHandler(JSContext *cx, JSScript *, jsbytecode *pc, jsval *rval,
|
||||
|
||||
/* Debug-mode currently disables Ion compilation. */
|
||||
JSStackFrame *caller = Jsvalify(iter.interpFrame());
|
||||
JSScript *script = iter.script();
|
||||
RawScript script = iter.script().unsafeGet();
|
||||
|
||||
size_t length;
|
||||
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
|
||||
@ -1778,11 +1778,11 @@ DisassembleScript(JSContext *cx, JSScript *script_, JSFunction *fun, bool lines,
|
||||
if (recursive && script->hasObjects()) {
|
||||
ObjectArray *objects = script->objects();
|
||||
for (unsigned i = 0; i != objects->length; ++i) {
|
||||
JSObject *obj = objects->vector[i];
|
||||
RawObject obj = objects->vector[i];
|
||||
if (obj->isFunction()) {
|
||||
Sprint(sp, "\n");
|
||||
JSFunction *fun = obj->toFunction();
|
||||
JSScript *nested = fun->maybeScript();
|
||||
RawFunction fun = obj->toFunction();
|
||||
RawScript nested = fun->maybeScript().unsafeGet();
|
||||
if (!DisassembleScript(cx, nested, fun, lines, recursive, sp))
|
||||
return false;
|
||||
}
|
||||
@ -2537,9 +2537,10 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
|
||||
StackFrame *fp = fi.interpFrame();
|
||||
RootedScript fpscript(cx, fp->script());
|
||||
bool ok = !!JS_EvaluateUCInStackFrame(cx, Jsvalify(fp), chars, length,
|
||||
fp->script()->filename,
|
||||
JS_PCToLineNumber(cx, fp->script(),
|
||||
fpscript->filename,
|
||||
JS_PCToLineNumber(cx, fpscript,
|
||||
fi.pc()),
|
||||
vp);
|
||||
|
||||
|
@ -69,6 +69,7 @@ ArgumentsObject::setArg(unsigned i, const Value &v)
|
||||
inline const Value &
|
||||
ArgumentsObject::element(uint32_t i) const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(!isElementDeleted(i));
|
||||
const Value &v = data()->args[i];
|
||||
if (v.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
|
||||
@ -84,6 +85,7 @@ ArgumentsObject::element(uint32_t i) const
|
||||
inline void
|
||||
ArgumentsObject::setElement(uint32_t i, const Value &v)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(!isElementDeleted(i));
|
||||
HeapValue &lhs = data()->args[i];
|
||||
if (lhs.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
|
||||
|
@ -48,7 +48,8 @@ CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
|
||||
/* static */ void
|
||||
ArgumentsObject::MaybeForwardToCallObject(StackFrame *fp, JSObject *obj, ArgumentsData *data)
|
||||
{
|
||||
JSScript *script = fp->script();
|
||||
AutoAssertNoGC nogc;
|
||||
RawScript script = fp->script();
|
||||
if (fp->fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
|
||||
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(fp->callObj()));
|
||||
for (AliasedFormalIter fi(script); fi; fi++)
|
||||
@ -119,6 +120,8 @@ template <typename CopyArgs>
|
||||
ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction callee, unsigned numActuals,
|
||||
CopyArgs ©)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
RootedObject proto(cx, callee->global().getOrCreateObjectPrototype(cx));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
@ -158,7 +161,7 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
|
||||
data->deletedBits = reinterpret_cast<size_t *>(dstEnd);
|
||||
ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
|
||||
|
||||
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, shape, type, NULL);
|
||||
RawObject obj = JSObject::create(cx, FINALIZE_KIND, shape, type, NULL);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
|
@ -572,7 +572,7 @@ Debugger::slowPathOnLeaveFrame(JSContext *cx, bool frameOk)
|
||||
* own Debugger.Frame instance.
|
||||
*/
|
||||
for (FrameRange r(fp, global); !r.empty(); r.popFront()) {
|
||||
JSObject *frameobj = r.frontFrame();
|
||||
RootedObject frameobj(cx, r.frontFrame());
|
||||
Debugger *dbg = r.frontDebugger();
|
||||
JS_ASSERT(dbg == Debugger::fromChildJSObject(frameobj));
|
||||
|
||||
@ -594,7 +594,7 @@ Debugger::slowPathOnLeaveFrame(JSContext *cx, bool frameOk)
|
||||
* script is about to be destroyed. Remove any breakpoints in it.
|
||||
*/
|
||||
if (fp->isEvalFrame()) {
|
||||
JSScript *script = fp->script();
|
||||
RootedScript script(cx, fp->script());
|
||||
script->clearBreakpointsIn(cx->runtime->defaultFreeOp(), NULL, NULL);
|
||||
}
|
||||
|
||||
@ -1042,9 +1042,8 @@ AddNewScriptRecipients(GlobalObject::DebuggerVector *src, AutoValueVector *dest)
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::slowPathOnNewScript(JSContext *cx, JSScript *script_, GlobalObject *compileAndGoGlobal_)
|
||||
Debugger::slowPathOnNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal_)
|
||||
{
|
||||
Rooted<JSScript*> script(cx, script_);
|
||||
Rooted<GlobalObject*> compileAndGoGlobal(cx, compileAndGoGlobal_);
|
||||
|
||||
JS_ASSERT(script->compileAndGo == !!compileAndGoGlobal);
|
||||
@ -1086,7 +1085,7 @@ JSTrapStatus
|
||||
Debugger::onTrap(JSContext *cx, Value *vp)
|
||||
{
|
||||
StackFrame *fp = cx->fp();
|
||||
Rooted<JSScript*> script(cx, fp->script());
|
||||
RootedScript script(cx, fp->script());
|
||||
Rooted<GlobalObject*> scriptGlobal(cx, &fp->global());
|
||||
jsbytecode *pc = cx->regs().pc;
|
||||
BreakpointSite *site = script->getBreakpointSite(pc);
|
||||
@ -1140,7 +1139,8 @@ Debugger::onTrap(JSContext *cx, Value *vp)
|
||||
}
|
||||
|
||||
if (site && site->trapHandler) {
|
||||
JSTrapStatus st = site->trapHandler(cx, fp->script(), pc, vp, site->trapClosure);
|
||||
RootedScript fpscript(cx, fp->script());
|
||||
JSTrapStatus st = site->trapHandler(cx, fpscript, pc, vp, site->trapClosure);
|
||||
if (st != JSTRAP_CONTINUE)
|
||||
return st;
|
||||
}
|
||||
@ -1193,6 +1193,7 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
|
||||
* be done with unit tests.
|
||||
*/
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
uint32_t stepperCount = 0;
|
||||
JSScript *trappingScript = fp->script();
|
||||
GlobalObject *global = &fp->global();
|
||||
@ -2237,13 +2238,15 @@ class Debugger::ScriptQuery {
|
||||
* this query, and append the matching scripts to |vector|.
|
||||
*/
|
||||
bool findScripts(AutoScriptVector *vector) {
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (!prepareQuery())
|
||||
return false;
|
||||
|
||||
/* Search each compartment for debuggee scripts. */
|
||||
for (CompartmentSet::Range r = compartments.all(); !r.empty(); r.popFront()) {
|
||||
for (gc::CellIter i(r.front(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
RawScript script = i.get<JSScript>();
|
||||
if (script->compileAndGo && !script->isForEval()) {
|
||||
if (!consider(script, &script->global(), vector))
|
||||
return false;
|
||||
@ -2257,7 +2260,7 @@ class Debugger::ScriptQuery {
|
||||
*/
|
||||
for (ScriptFrameIter fri(cx); !fri.done(); ++fri) {
|
||||
if (fri.isEvalFrame()) {
|
||||
JSScript *script = fri.script();
|
||||
RawScript script = fri.script();
|
||||
|
||||
/*
|
||||
* Eval scripts were not considered above so we don't need to
|
||||
@ -2739,13 +2742,15 @@ DebuggerScript_getChildScripts(JSContext *cx, unsigned argc, Value *vp)
|
||||
* It is not really a child script of this script, so skip it.
|
||||
*/
|
||||
ObjectArray *objects = script->objects();
|
||||
Rooted<JSScript*> funScript(cx);
|
||||
RootedFunction fun(cx);
|
||||
RootedScript funScript(cx);
|
||||
RootedObject obj(cx), s(cx);
|
||||
for (uint32_t i = script->savedCallerFun ? 1 : 0; i < objects->length; i++) {
|
||||
JSObject *obj = objects->vector[i];
|
||||
obj = objects->vector[i];
|
||||
if (obj->isFunction()) {
|
||||
JSFunction *fun = static_cast<JSFunction *>(obj);
|
||||
fun = static_cast<JSFunction *>(obj.get());
|
||||
funScript = fun->script();
|
||||
JSObject *s = dbg->wrapScript(cx, funScript);
|
||||
s = dbg->wrapScript(cx, funScript);
|
||||
if (!s || !js_NewbornArrayPush(cx, result, ObjectValue(*s)))
|
||||
return false;
|
||||
}
|
||||
@ -3333,6 +3338,7 @@ Class DebuggerArguments_class = {
|
||||
static JSBool
|
||||
DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
int32_t i = args.callee().toFunction()->getExtendedSlot(0).toInt32();
|
||||
|
||||
@ -3341,7 +3347,7 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
|
||||
ReportObjectRequired(cx);
|
||||
return false;
|
||||
}
|
||||
JSObject *argsobj = &args.thisv().toObject();
|
||||
RootedObject argsobj(cx, &args.thisv().toObject());
|
||||
if (argsobj->getClass() != &DebuggerArguments_class) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
"Arguments", "getArgument", argsobj->getClass()->name);
|
||||
@ -3360,9 +3366,10 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
|
||||
* there is no guarantee this object has an ith argument.
|
||||
*/
|
||||
JS_ASSERT(i >= 0);
|
||||
Value arg;
|
||||
RootedValue arg(cx);
|
||||
RootedScript script(cx);
|
||||
if (unsigned(i) < fp->numActualArgs()) {
|
||||
JSScript *script = fp->script();
|
||||
script = fp->script();
|
||||
if (unsigned(i) < fp->numFormalArgs() && script->formalIsAliased(i)) {
|
||||
for (AliasedFormalIter fi(script); ; fi++) {
|
||||
if (fi.frameIndex() == unsigned(i)) {
|
||||
@ -3379,7 +3386,7 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
|
||||
arg.setUndefined();
|
||||
}
|
||||
|
||||
if (!Debugger::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, &arg))
|
||||
if (!Debugger::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, arg.address()))
|
||||
return false;
|
||||
args.rval().set(arg);
|
||||
return true;
|
||||
@ -3451,11 +3458,11 @@ DebuggerFrame_getScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
THIS_FRAME(cx, argc, vp, "get script", args, thisobj, fp);
|
||||
Debugger *debug = Debugger::fromChildJSObject(thisobj);
|
||||
|
||||
JSObject *scriptObject = NULL;
|
||||
RootedObject scriptObject(cx);
|
||||
if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
|
||||
JSFunction &callee = fp->callee();
|
||||
if (callee.isInterpreted()) {
|
||||
Rooted<JSScript*> script(cx, callee.script());
|
||||
RootedScript script(cx, callee.script());
|
||||
scriptObject = debug->wrapScript(cx, script);
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
@ -3465,7 +3472,7 @@ DebuggerFrame_getScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
* We got eval, JS_Evaluate*, or JS_ExecuteScript non-function script
|
||||
* frames.
|
||||
*/
|
||||
Rooted<JSScript*> script(cx, fp->script());
|
||||
RootedScript script(cx, fp->script());
|
||||
scriptObject = debug->wrapScript(cx, script);
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
@ -3478,7 +3485,8 @@ static JSBool
|
||||
DebuggerFrame_getOffset(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_FRAME(cx, argc, vp, "get offset", args, thisobj, fp);
|
||||
JSScript *script = fp->script();
|
||||
AutoAssertNoGC nogc;
|
||||
RawScript script = fp->script();
|
||||
jsbytecode *pc = fp->pcQuadratic(cx);
|
||||
JS_ASSERT(script->code <= pc);
|
||||
JS_ASSERT(pc < script->code + script->length);
|
||||
@ -3782,6 +3790,7 @@ Class DebuggerObject_class = {
|
||||
static JSObject *
|
||||
DebuggerObject_checkThis(JSContext *cx, const CallArgs &args, const char *fnname)
|
||||
{
|
||||
AssertCanGC();
|
||||
if (!args.thisv().isObject()) {
|
||||
ReportObjectRequired(cx);
|
||||
return NULL;
|
||||
@ -3826,6 +3835,7 @@ DebuggerObject_checkThis(JSContext *cx, const CallArgs &args, const char *fnname
|
||||
static JSBool
|
||||
DebuggerObject_construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, "Debugger.Object");
|
||||
return false;
|
||||
}
|
||||
@ -3833,6 +3843,7 @@ DebuggerObject_construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getProto(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get proto", args, dbg, refobj);
|
||||
RootedObject proto(cx);
|
||||
{
|
||||
@ -3850,6 +3861,7 @@ DebuggerObject_getProto(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getClass(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, "get class", args, refobj);
|
||||
const char *s = refobj->getClass()->name;
|
||||
JSAtom *str = Atomize(cx, s, strlen(s));
|
||||
@ -3870,6 +3882,7 @@ DebuggerObject_getCallable(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getName(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get name", args, dbg, obj);
|
||||
if (!obj->isFunction()) {
|
||||
args.rval().setUndefined();
|
||||
@ -3892,6 +3905,7 @@ DebuggerObject_getName(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getDisplayName(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get display name", args, dbg, obj);
|
||||
if (!obj->isFunction()) {
|
||||
args.rval().setUndefined();
|
||||
@ -3914,6 +3928,7 @@ DebuggerObject_getDisplayName(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getParameterNames(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, "get parameterNames", args, obj);
|
||||
if (!obj->isFunction()) {
|
||||
args.rval().setUndefined();
|
||||
@ -3955,6 +3970,7 @@ DebuggerObject_getParameterNames(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get script", args, dbg, obj);
|
||||
|
||||
if (!obj->isFunction()) {
|
||||
@ -3962,14 +3978,14 @@ DebuggerObject_getScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSFunction *fun = obj->toFunction();
|
||||
RootedFunction fun(cx, obj->toFunction());
|
||||
if (!fun->isInterpreted()) {
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rooted<JSScript*> script(cx, fun->script());
|
||||
JSObject *scriptObject = dbg->wrapScript(cx, script);
|
||||
RootedScript script(cx, fun->script());
|
||||
RootedObject scriptObject(cx, dbg->wrapScript(cx, script));
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
|
||||
@ -3980,6 +3996,7 @@ DebuggerObject_getScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getEnvironment(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get environment", args, dbg, obj);
|
||||
|
||||
/* Don't bother switching compartments just to check obj's type and get its env. */
|
||||
@ -4014,6 +4031,7 @@ DebuggerObject_getGlobal(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyDescriptor", args, dbg, obj);
|
||||
|
||||
RootedId id(cx);
|
||||
@ -4057,6 +4075,7 @@ DebuggerObject_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
||||
static JSBool
|
||||
DebuggerObject_getOwnPropertyNames(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
AssertCanGC();
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyNames", args, dbg, obj);
|
||||
|
||||
AutoIdVector keys(cx);
|
||||
|
@ -192,7 +192,7 @@ class Debugger {
|
||||
|
||||
static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, Value *vp);
|
||||
static bool slowPathOnLeaveFrame(JSContext *cx, bool ok);
|
||||
static void slowPathOnNewScript(JSContext *cx, JSScript *script,
|
||||
static void slowPathOnNewScript(JSContext *cx, HandleScript script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static bool slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||
static JSTrapStatus dispatchHook(JSContext *cx, Value *vp, Hook which);
|
||||
@ -256,7 +256,7 @@ class Debugger {
|
||||
static inline bool onLeaveFrame(JSContext *cx, bool ok);
|
||||
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, Value *vp);
|
||||
static inline JSTrapStatus onExceptionUnwind(JSContext *cx, Value *vp);
|
||||
static inline void onNewScript(JSContext *cx, JSScript *script,
|
||||
static inline void onNewScript(JSContext *cx, HandleScript script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static inline bool onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||
static JSTrapStatus onTrap(JSContext *cx, Value *vp);
|
||||
@ -544,7 +544,7 @@ Debugger::onExceptionUnwind(JSContext *cx, Value *vp)
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::onNewScript(JSContext *cx, JSScript *script, GlobalObject *compileAndGoGlobal)
|
||||
Debugger::onNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal)
|
||||
{
|
||||
JS_ASSERT_IF(script->compileAndGo, compileAndGoGlobal);
|
||||
JS_ASSERT_IF(!script->compileAndGo, !compileAndGoGlobal);
|
||||
|
@ -204,7 +204,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
/* Create |Function.prototype| next so we can create other functions. */
|
||||
RootedFunction functionProto(cx);
|
||||
{
|
||||
JSObject *functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self);
|
||||
RawObject functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self);
|
||||
if (!functionProto_)
|
||||
return NULL;
|
||||
functionProto = functionProto_->toFunction();
|
||||
@ -213,12 +213,14 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
* Bizarrely, |Function.prototype| must be an interpreted function, so
|
||||
* give it the guts to be one.
|
||||
*/
|
||||
JSObject *proto = js_NewFunction(cx, functionProto,
|
||||
NULL, 0, JSFUN_INTERPRETED, self, NullPtr());
|
||||
if (!proto)
|
||||
return NULL;
|
||||
JS_ASSERT(proto == functionProto);
|
||||
functionProto->flags |= JSFUN_PROTOTYPE;
|
||||
{
|
||||
RawObject proto = js_NewFunction(cx, functionProto,
|
||||
NULL, 0, JSFUN_INTERPRETED, self, NullPtr());
|
||||
if (!proto)
|
||||
return NULL;
|
||||
JS_ASSERT(proto == functionProto);
|
||||
functionProto->flags |= JSFUN_PROTOTYPE;
|
||||
}
|
||||
|
||||
const char *rawSource = "() {\n}";
|
||||
size_t sourceLen = strlen(rawSource);
|
||||
@ -236,14 +238,14 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
CompileOptions options(cx);
|
||||
options.setNoScriptRval(true)
|
||||
.setVersion(JSVERSION_DEFAULT);
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx,
|
||||
/* enclosingScope = */ NullPtr(),
|
||||
/* savedCallerFun = */ false,
|
||||
options,
|
||||
/* staticLevel = */ 0,
|
||||
ss,
|
||||
0,
|
||||
ss->length()));
|
||||
RootedScript script(cx, JSScript::Create(cx,
|
||||
/* enclosingScope = */ NullPtr(),
|
||||
/* savedCallerFun = */ false,
|
||||
options,
|
||||
/* staticLevel = */ 0,
|
||||
ss,
|
||||
0,
|
||||
ss->length()));
|
||||
if (!script || !JSScript::fullyInitTrivial(cx, script))
|
||||
return NULL;
|
||||
|
||||
@ -347,18 +349,16 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
}
|
||||
|
||||
/* Add the global Function and Object properties now. */
|
||||
jsid objectId = NameToId(cx->names().Object);
|
||||
if (!self->addDataProperty(cx, objectId, JSProto_Object + JSProto_LIMIT * 2, 0))
|
||||
if (!self->addDataProperty(cx, NameToId(cx->names().Object), JSProto_Object + JSProto_LIMIT * 2, 0))
|
||||
return NULL;
|
||||
jsid functionId = NameToId(cx->names().Function);
|
||||
if (!self->addDataProperty(cx, functionId, JSProto_Function + JSProto_LIMIT * 2, 0))
|
||||
if (!self->addDataProperty(cx, NameToId(cx->names().Function), JSProto_Function + JSProto_LIMIT * 2, 0))
|
||||
return NULL;
|
||||
|
||||
/* Heavy lifting done, but lingering tasks remain. */
|
||||
|
||||
/* ES5 15.1.2.1. */
|
||||
RootedId id(cx, NameToId(cx->names().eval));
|
||||
JSObject *evalobj = js_DefineFunction(cx, self, id, IndirectEval, 1, JSFUN_STUB_GSOPS);
|
||||
RootedId evalId(cx, NameToId(cx->names().eval));
|
||||
RawObject evalobj = js_DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
|
||||
if (!evalobj)
|
||||
return NULL;
|
||||
self->setOriginalEval(evalobj);
|
||||
@ -401,7 +401,8 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
||||
* Notify any debuggers about the creation of the script for
|
||||
* |Function.prototype| -- after all initialization, for simplicity.
|
||||
*/
|
||||
js_CallNewScriptHook(cx, functionProto->script(), functionProto);
|
||||
RootedScript functionProtoScript(cx, functionProto->script());
|
||||
js_CallNewScriptHook(cx, functionProtoScript, functionProto);
|
||||
return functionProto;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ StaticScopeIter::block() const
|
||||
JSScript *
|
||||
StaticScopeIter::funScript() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT(type() == FUNCTION);
|
||||
return obj->toFunction()->script();
|
||||
}
|
||||
@ -184,7 +185,7 @@ CallObject::createTemplateObject(JSContext *cx, JSScript *script)
|
||||
* must be null.
|
||||
*/
|
||||
CallObject *
|
||||
CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleFunction callee)
|
||||
CallObject::create(JSContext *cx, HandleScript script, HandleObject enclosing, HandleFunction callee)
|
||||
{
|
||||
CallObject *callobj = CallObject::createTemplateObject(cx, script);
|
||||
if (!callobj)
|
||||
@ -198,6 +199,7 @@ CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, Hand
|
||||
CallObject *
|
||||
CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(fp->isNonEvalFunctionFrame());
|
||||
assertSameCompartment(cx, fp);
|
||||
|
||||
@ -214,7 +216,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
||||
}
|
||||
|
||||
RootedScript script(cx, fp->script());
|
||||
Rooted<JSFunction*> callee(cx, &fp->callee());
|
||||
RootedFunction callee(cx, &fp->callee());
|
||||
CallObject *callobj = create(cx, script, scopeChain, callee);
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
@ -229,12 +231,14 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
||||
CallObject *
|
||||
CallObject::createForStrictEval(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(fp->isStrictEvalFrame());
|
||||
JS_ASSERT(cx->fp() == fp);
|
||||
JS_ASSERT(cx->regs().pc == fp->script()->code);
|
||||
|
||||
Rooted<JSFunction*> callee(cx, NULL);
|
||||
return create(cx, fp->script(), fp->scopeChain(), callee);
|
||||
RootedFunction callee(cx);
|
||||
RootedScript script(cx, fp->script());
|
||||
return create(cx, script, fp->scopeChain(), callee);
|
||||
}
|
||||
|
||||
JS_PUBLIC_DATA(Class) js::CallClass = {
|
||||
@ -314,7 +318,7 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui
|
||||
obj->asScope().setEnclosingScope(enclosing);
|
||||
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
|
||||
|
||||
JSObject *thisp = JSObject::thisObject(cx, proto);
|
||||
RawObject thisp = JSObject::thisObject(cx, proto);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
|
||||
@ -630,6 +634,7 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Stac
|
||||
void
|
||||
ClonedBlockObject::copyUnaliasedValues(StackFrame *fp)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StaticBlockObject &block = staticBlock();
|
||||
unsigned base = fp->script()->nfixed + block.stackDepth();
|
||||
for (unsigned i = 0; i < slotCount(); ++i) {
|
||||
@ -975,6 +980,7 @@ ScopeIter::operator++()
|
||||
void
|
||||
ScopeIter::settle()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
/*
|
||||
* Given an iterator state (cur_, block_), figure out which (potentially
|
||||
* optimized) scope the iterator should report. Thus, the result is a pair
|
||||
@ -1196,12 +1202,13 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (!shape)
|
||||
return false;
|
||||
|
||||
AutoAssertNoGC nogc;
|
||||
unsigned i = shape->shortid();
|
||||
if (block.staticBlock().isAliased(i))
|
||||
return false;
|
||||
|
||||
if (maybefp) {
|
||||
JSScript *script = maybefp->script();
|
||||
RawScript script = maybefp->script();
|
||||
unsigned local = block.slotToLocalIndex(script->bindings, shape->slot());
|
||||
if (action == GET)
|
||||
*vp = maybefp->unaliasedLocal(local);
|
||||
@ -1254,13 +1261,13 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
static bool checkForMissingArguments(JSContext *cx, jsid id, ScopeObject &scope,
|
||||
ArgumentsObject **maybeArgsObj)
|
||||
{
|
||||
AssertCanGC();
|
||||
*maybeArgsObj = NULL;
|
||||
|
||||
if (!isArguments(cx, id) || !isFunctionScope(scope))
|
||||
return true;
|
||||
|
||||
JSScript *script = scope.asCall().callee().script();
|
||||
if (script->needsArgsObj())
|
||||
if (scope.asCall().callee().script()->needsArgsObj())
|
||||
return true;
|
||||
|
||||
StackFrame *maybefp = cx->runtime->debugScopes->hasLiveFrame(scope);
|
||||
@ -1711,7 +1718,7 @@ DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
* Copy in formals that are not aliased via the scope chain
|
||||
* but are aliased via the arguments object.
|
||||
*/
|
||||
JSScript *script = fp->script();
|
||||
RootedScript script(cx, fp->script());
|
||||
if (script->needsArgsObj() && fp->hasArgsObj()) {
|
||||
for (unsigned i = 0; i < fp->numFormalArgs(); ++i) {
|
||||
if (script->formalLivesInArgumentsObject(i))
|
||||
@ -1723,7 +1730,7 @@ DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
* Use a dense array as storage (since proxies do not have trace
|
||||
* hooks). This array must not escape into the wild.
|
||||
*/
|
||||
JSObject *snapshot = NewDenseCopiedArray(cx, vec.length(), vec.begin());
|
||||
RootedObject snapshot(cx, NewDenseCopiedArray(cx, vec.length(), vec.begin()));
|
||||
if (!snapshot) {
|
||||
cx->clearPendingException();
|
||||
return;
|
||||
|
@ -181,7 +181,7 @@ class CallObject : public ScopeObject
|
||||
static const uint32_t CALLEE_SLOT = 1;
|
||||
|
||||
static CallObject *
|
||||
create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleFunction callee);
|
||||
create(JSContext *cx, HandleScript script, HandleObject enclosing, HandleFunction callee);
|
||||
|
||||
public:
|
||||
/* These functions are internal and are exposed only for JITs. */
|
||||
|
@ -74,8 +74,8 @@ StackFrame::compartment() const
|
||||
inline mjit::JITScript *
|
||||
StackFrame::jit()
|
||||
{
|
||||
JSScript *script_ = script();
|
||||
return script_->getJIT(isConstructing(), script_->compartment()->compileBarriers());
|
||||
AutoAssertNoGC nogc;
|
||||
return script()->getJIT(isConstructing(), script()->compartment()->compileBarriers());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -133,6 +133,7 @@ inline void
|
||||
StackFrame::initCallFrame(JSContext *cx, JSFunction &callee,
|
||||
JSScript *script, uint32_t nactual, StackFrame::Flags flagsArg)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT((flagsArg & ~(CONSTRUCTING |
|
||||
LOWERED_CALL_APPLY |
|
||||
OVERFLOW_ARGS |
|
||||
@ -192,6 +193,7 @@ StackFrame::jitHeavyweightFunctionPrologue(JSContext *cx)
|
||||
inline void
|
||||
StackFrame::initVarsToUndefined()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
SetValueRangeToUndefined(slots(), script()->nfixed);
|
||||
}
|
||||
|
||||
@ -207,6 +209,7 @@ StackFrame::createRestParameter(JSContext *cx)
|
||||
inline Value &
|
||||
StackFrame::unaliasedVar(unsigned i, MaybeCheckAliasing checkAliasing)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
JS_ASSERT_IF(checkAliasing, !script()->varIsAliased(i));
|
||||
JS_ASSERT(i < script()->nfixed);
|
||||
return slots()[i];
|
||||
@ -216,6 +219,7 @@ inline Value &
|
||||
StackFrame::unaliasedLocal(unsigned i, MaybeCheckAliasing checkAliasing)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
AutoAssertNoGC nogc;
|
||||
if (checkAliasing) {
|
||||
JS_ASSERT(i < script()->nslots);
|
||||
if (i < script()->nfixed) {
|
||||
@ -379,6 +383,7 @@ STATIC_POSTCONDITION(!return || ubound(from) >= nvals)
|
||||
JS_ALWAYS_INLINE bool
|
||||
StackSpace::ensureSpace(JSContext *cx, MaybeReportError report, Value *from, ptrdiff_t nvals) const
|
||||
{
|
||||
AssertCanGC();
|
||||
assertInvariants();
|
||||
JS_ASSERT(from >= firstUnused());
|
||||
#ifdef XP_WIN
|
||||
@ -392,6 +397,7 @@ StackSpace::ensureSpace(JSContext *cx, MaybeReportError report, Value *from, ptr
|
||||
inline Value *
|
||||
StackSpace::getStackLimit(JSContext *cx, MaybeReportError report)
|
||||
{
|
||||
AssertCanGC();
|
||||
FrameRegs ®s = cx->regs();
|
||||
unsigned nvals = regs.fp()->script()->nslots + STACK_JIT_EXTRA;
|
||||
return ensureSpace(cx, report, regs.sp, nvals)
|
||||
@ -405,6 +411,7 @@ JS_ALWAYS_INLINE StackFrame *
|
||||
ContextStack::getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args,
|
||||
JSFunction *fun, JSScript *script, StackFrame::Flags *flags) const
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(fun->script() == script);
|
||||
unsigned nformal = fun->nargs;
|
||||
|
||||
@ -446,10 +453,11 @@ ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &ar
|
||||
JSFunction &callee, JSScript *script,
|
||||
InitialFrameFlags initial, MaybeReportError report)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(onTop());
|
||||
JS_ASSERT(regs.sp == args.end());
|
||||
/* Cannot assert callee == args.callee() since this is called from LeaveTree. */
|
||||
JS_ASSERT(script == callee.script());
|
||||
JS_ASSERT(callee.script() == script);
|
||||
|
||||
StackFrame::Flags flags = ToFrameFlags(initial);
|
||||
StackFrame *fp = getCallFrame(cx, report, args, &callee, script, &flags);
|
||||
@ -472,6 +480,7 @@ ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &ar
|
||||
JSFunction &callee, JSScript *script,
|
||||
InitialFrameFlags initial, Value **stackLimit)
|
||||
{
|
||||
AssertCanGC();
|
||||
if (!pushInlineFrame(cx, regs, args, callee, script, initial))
|
||||
return false;
|
||||
*stackLimit = space().conservativeEnd_;
|
||||
@ -483,6 +492,7 @@ ContextStack::getFixupFrame(JSContext *cx, MaybeReportError report,
|
||||
const CallArgs &args, JSFunction *fun, JSScript *script,
|
||||
void *ncode, InitialFrameFlags initial, Value **stackLimit)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(onTop());
|
||||
JS_ASSERT(fun->script() == args.callee().toFunction()->script());
|
||||
JS_ASSERT(fun->script() == script);
|
||||
@ -526,6 +536,8 @@ inline JSScript *
|
||||
ContextStack::currentScript(jsbytecode **ppc,
|
||||
MaybeAllowCrossCompartment allowCrossCompartment) const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
if (ppc)
|
||||
*ppc = NULL;
|
||||
|
||||
@ -551,7 +563,7 @@ ContextStack::currentScript(jsbytecode **ppc,
|
||||
mjit::JITChunk *chunk = fp->jit()->chunk(regs.pc);
|
||||
JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
|
||||
mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
|
||||
JSScript *script = frame->fun->script();
|
||||
RawScript script = frame->fun->script();
|
||||
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
|
||||
return NULL;
|
||||
if (ppc)
|
||||
@ -560,7 +572,7 @@ ContextStack::currentScript(jsbytecode **ppc,
|
||||
}
|
||||
#endif
|
||||
|
||||
JSScript *script = fp->script();
|
||||
RawScript script = fp->script();
|
||||
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
|
||||
return NULL;
|
||||
|
||||
|
@ -245,7 +245,7 @@ AssertDynamicScopeMatchesStaticScope(JSScript *script, JSObject *scope)
|
||||
scope = &scope->asClonedBlock().enclosingScope();
|
||||
break;
|
||||
case StaticScopeIter::FUNCTION:
|
||||
JS_ASSERT(i.funScript() == scope->asCall().callee().script());
|
||||
JS_ASSERT(scope->asCall().callee().script() == i.funScript());
|
||||
scope = &scope->asCall().enclosingScope();
|
||||
break;
|
||||
case StaticScopeIter::NAMED_LAMBDA:
|
||||
@ -276,28 +276,30 @@ StackFrame::initCallObject(JSContext *cx)
|
||||
bool
|
||||
StackFrame::prologue(JSContext *cx, bool newType)
|
||||
{
|
||||
RootedScript script(cx, this->script());
|
||||
|
||||
JS_ASSERT(!isGeneratorFrame());
|
||||
JS_ASSERT(cx->regs().pc == script()->code);
|
||||
JS_ASSERT(cx->regs().pc == script->code);
|
||||
|
||||
if (isEvalFrame()) {
|
||||
if (script()->strictModeCode) {
|
||||
if (script->strictModeCode) {
|
||||
CallObject *callobj = CallObject::createForStrictEval(cx, this);
|
||||
if (!callobj)
|
||||
return false;
|
||||
pushOnScopeChain(*callobj);
|
||||
flags_ |= HAS_CALL_OBJ;
|
||||
}
|
||||
Probes::enterScript(cx, script(), NULL, this);
|
||||
Probes::enterScript(cx, script, NULL, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isGlobalFrame()) {
|
||||
Probes::enterScript(cx, script(), NULL, this);
|
||||
Probes::enterScript(cx, script, NULL, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_ASSERT(isNonEvalFunctionFrame());
|
||||
AssertDynamicScopeMatchesStaticScope(script(), scopeChain());
|
||||
AssertDynamicScopeMatchesStaticScope(script, scopeChain());
|
||||
|
||||
if (fun()->isHeavyweight() && !initCallObject(cx))
|
||||
return false;
|
||||
@ -310,7 +312,7 @@ StackFrame::prologue(JSContext *cx, bool newType)
|
||||
functionThis() = ObjectValue(*obj);
|
||||
}
|
||||
|
||||
Probes::enterScript(cx, script(), script()->function(), this);
|
||||
Probes::enterScript(cx, script, script->function(), this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -320,7 +322,8 @@ StackFrame::epilogue(JSContext *cx)
|
||||
JS_ASSERT(!isYielding());
|
||||
JS_ASSERT(!hasBlockChain());
|
||||
|
||||
Probes::exitScript(cx, script(), script()->function(), this);
|
||||
RootedScript script(cx, this->script());
|
||||
Probes::exitScript(cx, script, script->function(), this);
|
||||
|
||||
if (isEvalFrame()) {
|
||||
if (isStrictEvalFrame()) {
|
||||
@ -356,9 +359,9 @@ StackFrame::epilogue(JSContext *cx)
|
||||
JS_ASSERT(isNonEvalFunctionFrame());
|
||||
|
||||
if (fun()->isHeavyweight())
|
||||
JS_ASSERT_IF(hasCallObj(), scopeChain()->asCall().callee().script() == script());
|
||||
JS_ASSERT_IF(hasCallObj(), scopeChain()->asCall().callee().script() == script);
|
||||
else
|
||||
AssertDynamicScopeMatchesStaticScope(script(), scopeChain());
|
||||
AssertDynamicScopeMatchesStaticScope(script, scopeChain());
|
||||
|
||||
if (cx->compartment->debugMode())
|
||||
cx->runtime->debugScopes->onPopCall(this, cx);
|
||||
@ -632,12 +635,13 @@ StackSpace::containingSegment(const StackFrame *target) const
|
||||
void
|
||||
StackSpace::markAndClobberFrame(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbytecode *pc)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
Value *slotsBegin = fp->slots();
|
||||
|
||||
/* If it's a scripted frame, we should have a pc. */
|
||||
JS_ASSERT(pc);
|
||||
|
||||
JSScript *script = fp->script();
|
||||
RawScript script = fp->script();
|
||||
if (!script->hasAnalysis() || !script->analysis()->ranLifetimes()) {
|
||||
if (trc)
|
||||
gc::MarkValueRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
|
||||
@ -750,6 +754,7 @@ StackSpace::markActiveCompartments()
|
||||
JS_FRIEND_API(bool)
|
||||
StackSpace::ensureSpaceSlow(JSContext *cx, MaybeReportError report, Value *from, ptrdiff_t nvals) const
|
||||
{
|
||||
AssertCanGC();
|
||||
assertInvariants();
|
||||
|
||||
JSCompartment *dest = cx->compartment;
|
||||
@ -929,6 +934,8 @@ Value *
|
||||
ContextStack::ensureOnTop(JSContext *cx, MaybeReportError report, unsigned nvars,
|
||||
MaybeExtend extend, bool *pushedSeg)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
Value *firstUnused = space().firstUnused();
|
||||
FrameRegs *regs = cx->maybeRegs();
|
||||
|
||||
@ -1007,6 +1014,7 @@ bool
|
||||
ContextStack::pushInvokeArgs(JSContext *cx, unsigned argc, InvokeArgsGuard *iag,
|
||||
MaybeReportError report)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(argc <= StackSpace::ARGS_LENGTH_MAX);
|
||||
|
||||
unsigned nvars = 2 + argc;
|
||||
@ -1045,10 +1053,11 @@ ContextStack::pushInvokeFrame(JSContext *cx, MaybeReportError report,
|
||||
const CallArgs &args, JSFunction *fun,
|
||||
InitialFrameFlags initial, FrameGuard *fg)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(onTop());
|
||||
JS_ASSERT(space().firstUnused() == args.end());
|
||||
|
||||
JSScript *script = fun->script();
|
||||
RootedScript script(cx, fun->script());
|
||||
|
||||
StackFrame::Flags flags = ToFrameFlags(initial);
|
||||
StackFrame *fp = getCallFrame(cx, report, args, fun, script, &flags);
|
||||
@ -1080,6 +1089,8 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
|
||||
JSObject &scopeChain, ExecuteType type,
|
||||
StackFrame *evalInFrame, ExecuteFrameGuard *efg)
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
/*
|
||||
* Even though global code and indirect eval do not execute in the context
|
||||
* of the current frame, prev-link these to the current frame so that the
|
||||
@ -1181,6 +1192,7 @@ ContextStack::popFrame(const FrameGuard &fg)
|
||||
bool
|
||||
ContextStack::pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrameGuard *gfg)
|
||||
{
|
||||
AssertCanGC();
|
||||
HeapValue *genvp = gen->stackSnapshot;
|
||||
JS_ASSERT(genvp == HeapValueify(gen->fp->generatorArgsSnapshotBegin()));
|
||||
unsigned vplen = HeapValueify(gen->fp->generatorArgsSnapshotEnd()) - genvp;
|
||||
@ -1250,6 +1262,8 @@ ContextStack::popGeneratorFrame(const GeneratorFrameGuard &gfg)
|
||||
bool
|
||||
ContextStack::saveFrameChain()
|
||||
{
|
||||
AssertCanGC();
|
||||
|
||||
bool pushedSeg;
|
||||
if (!ensureOnTop(cx_, REPORT_ERROR, 0, CANT_EXTEND, &pushedSeg))
|
||||
return false;
|
||||
@ -1283,6 +1297,7 @@ StackIter::poisonRegs()
|
||||
void
|
||||
StackIter::popFrame()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StackFrame *oldfp = fp_;
|
||||
JS_ASSERT(seg_->contains(oldfp));
|
||||
fp_ = fp_->prev();
|
||||
@ -1310,6 +1325,7 @@ StackIter::popCall()
|
||||
void
|
||||
StackIter::settleOnNewSegment()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
if (FrameRegs *regs = seg_->maybeRegs()) {
|
||||
pc_ = regs->pc;
|
||||
if (fp_)
|
||||
@ -1350,6 +1366,8 @@ StackIter::startOnSegment(StackSegment *seg)
|
||||
void
|
||||
StackIter::settleOnNewState()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* There are elements of the calls_ and fp_ chains that we want to skip
|
||||
* over so iterate until we settle on one or until there are no more.
|
||||
@ -1494,6 +1512,7 @@ StackIter::StackIter(JSRuntime *rt, StackSegment &seg)
|
||||
void
|
||||
StackIter::popIonFrame()
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
// Keep fp which describes all ion frames.
|
||||
poisonRegs();
|
||||
if (ionFrames_.isScripted() && ionInlineFrames_.more()) {
|
||||
@ -1553,7 +1572,7 @@ StackIter::operator++()
|
||||
settleOnNewState();
|
||||
break;
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
#ifdef JS_ION
|
||||
popIonFrame();
|
||||
break;
|
||||
#else
|
||||
@ -1603,7 +1622,7 @@ StackIter::isFunctionFrame() const
|
||||
case SCRIPTED:
|
||||
return interpFrame()->isFunctionFrame();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.isFunctionFrame();
|
||||
#else
|
||||
break;
|
||||
@ -1655,7 +1674,7 @@ StackIter::isConstructing() const
|
||||
case DONE:
|
||||
break;
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.isConstructing();
|
||||
#else
|
||||
break;
|
||||
@ -1685,7 +1704,7 @@ StackIter::callee() const
|
||||
return ionFrames_.callee();
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case NATIVE:
|
||||
return nativeArgs().callee().toFunction();
|
||||
}
|
||||
@ -1791,6 +1810,7 @@ StackIter::thisv() const
|
||||
size_t
|
||||
StackIter::numFrameSlots() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
switch (state_) {
|
||||
case DONE:
|
||||
case NATIVE:
|
||||
@ -1813,6 +1833,7 @@ StackIter::numFrameSlots() const
|
||||
Value
|
||||
StackIter::frameSlotValue(size_t index) const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
switch (state_) {
|
||||
case DONE:
|
||||
case NATIVE:
|
||||
|
@ -581,7 +581,7 @@ class StackFrame
|
||||
void popBlock(JSContext *cx);
|
||||
|
||||
/*
|
||||
* With
|
||||
* With
|
||||
*
|
||||
* Entering/leaving a with (or E4X filter) block pushes/pops an object
|
||||
* on the scope chain. Pushing uses pushOnScopeChain, popping should use
|
||||
@ -605,12 +605,12 @@ class StackFrame
|
||||
* the same VMFrame. Other calls force expansion of the inlined frames.
|
||||
*/
|
||||
|
||||
HandleScript script() const {
|
||||
js::Return<JSScript*> script() const {
|
||||
return isFunctionFrame()
|
||||
? isEvalFrame()
|
||||
? HandleScript::fromMarkedLocation(&u.evalScript)
|
||||
: fun()->script()
|
||||
: HandleScript::fromMarkedLocation(&exec.script);
|
||||
? u.evalScript
|
||||
: (JSScript*)fun()->script().unsafeGet()
|
||||
: exec.script;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1195,7 +1195,8 @@ class FrameRegs
|
||||
}
|
||||
|
||||
void setToEndOfScript() {
|
||||
JSScript *script = fp()->script();
|
||||
AutoAssertNoGC nogc;
|
||||
RawScript script = fp()->script();
|
||||
sp = fp()->base();
|
||||
pc = script->code + script->length - JSOP_STOP_LENGTH;
|
||||
JS_ASSERT(*pc == JSOP_STOP);
|
||||
@ -1789,7 +1790,7 @@ class StackIter
|
||||
StackFrame *interpFrame() const { JS_ASSERT(isScript() && !isIon()); return fp_; }
|
||||
|
||||
jsbytecode *pc() const { JS_ASSERT(isScript()); return pc_; }
|
||||
JSScript *script() const { JS_ASSERT(isScript()); return script_; }
|
||||
js::Return<JSScript*> script() const { JS_ASSERT(isScript()); return script_; }
|
||||
JSFunction *callee() const;
|
||||
Value calleev() const;
|
||||
unsigned numActualArgs() const;
|
||||
|
@ -341,6 +341,7 @@ js::StaticStrings::getInt(int32_t i)
|
||||
inline JSLinearString *
|
||||
js::StaticStrings::getUnitStringForElement(JSContext *cx, JSString *str, size_t index)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(index < str->length());
|
||||
const jschar *chars = str->getChars(cx);
|
||||
if (!chars)
|
||||
|
@ -288,7 +288,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
||||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(d94c13ae-7585-4e7b-b7ad-482976bc6f1b)]
|
||||
[uuid(e28a33ce-dfe9-4816-ae20-0f1dc8077230)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
@ -524,9 +524,7 @@ interface nsIXPConnect : nsISupports
|
||||
in JSObjectPtr aNewParent,
|
||||
in nsISupports aCOMObj);
|
||||
void
|
||||
moveWrappers(in JSContextPtr aJSContext,
|
||||
in JSObjectPtr aOldScope,
|
||||
in JSObjectPtr aNewScope);
|
||||
rescueOrphansInScope(in JSContextPtr aJSContext, in JSObjectPtr aScope);
|
||||
|
||||
void clearAllWrappedNativeSecurityPolicies();
|
||||
|
||||
|
@ -1850,7 +1850,7 @@ main(int argc, char **argv, char **envp)
|
||||
nsresult rv = rtsvc->GetBackstagePass(getter_AddRefs(backstagePass));
|
||||
if (NS_FAILED(rv)) {
|
||||
fprintf(gErrFile, "+++ Failed to get backstage pass from rtsvc: %8x\n",
|
||||
rv);
|
||||
static_cast<uint32_t>(rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
using namespace xpc;
|
||||
|
||||
@ -1706,17 +1707,6 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
XPCWrappedNative*
|
||||
XPCWrappedNative::GetParentWrapper()
|
||||
{
|
||||
XPCWrappedNative *wrapper = nullptr;
|
||||
JSObject *parent = js::GetObjectParent(mFlatJSObject);
|
||||
if (parent && IS_WN_WRAPPER(parent)) {
|
||||
wrapper = static_cast<XPCWrappedNative*>(js::GetObjectPrivate(parent));
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
// Orphans are sad little things - If only we could treat them better. :-(
|
||||
//
|
||||
// When a wrapper gets reparented to another scope (for example, when calling
|
||||
@ -1754,15 +1744,50 @@ XPCWrappedNative::IsOrphan()
|
||||
nsresult
|
||||
XPCWrappedNative::RescueOrphans(XPCCallContext& ccx)
|
||||
{
|
||||
//
|
||||
// Even if we're not an orphan at the moment, one of our ancestors might
|
||||
// be. If so, we need to recursively rescue up the parent chain.
|
||||
//
|
||||
|
||||
// First, get the parent object. If we're currently an orphan, the parent
|
||||
// object is a cross-compartment wrapper. Follow the parent into its own
|
||||
// compartment and fix it up there. We'll fix up |this| afterwards.
|
||||
//
|
||||
// NB: We pass stopAtOuter=false during the unwrap because Location objects
|
||||
// are parented to outer window proxies.
|
||||
nsresult rv;
|
||||
XPCWrappedNative *parentWrapper = GetParentWrapper();
|
||||
if (parentWrapper && parentWrapper->IsOrphan()) {
|
||||
rv = parentWrapper->RescueOrphans(ccx);
|
||||
JSObject *parentObj = js::GetObjectParent(mFlatJSObject);
|
||||
if (!parentObj)
|
||||
return NS_OK; // Global object. We're done.
|
||||
parentObj = js::UnwrapObject(parentObj, /* stopAtOuter = */ false);
|
||||
|
||||
// There's one little nasty twist here. For reasons described in bug 752764,
|
||||
// we nuke SOW-ed objects after transplanting them. This means that nodes
|
||||
// parented to an element (such as XUL elements), can end up with a nuked proxy
|
||||
// in the parent chain, depending on the order of fixup. Because the proxy is
|
||||
// nuked, we can't follow it anywhere. But we _can_ find the new wrapper for
|
||||
// the underlying native parent, which is exactly what PreCreate does.
|
||||
// So do that here.
|
||||
if (MOZ_UNLIKELY(JS_IsDeadWrapper(parentObj))) {
|
||||
rv = mScriptableInfo->GetCallback()->PreCreate(mIdentity, ccx,
|
||||
GetScope()->GetGlobalJSObject(),
|
||||
&parentObj);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Morph any slim wrappers, lest they confuse us.
|
||||
MOZ_ASSERT(IS_WRAPPER_CLASS(js::GetObjectClass(parentObj)));
|
||||
if (IS_SLIM_WRAPPER_OBJECT(parentObj)) {
|
||||
bool ok = MorphSlimWrapper(ccx, parentObj);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// Get the WN corresponding to the parent, and recursively fix it up.
|
||||
XPCWrappedNative *parentWrapper =
|
||||
static_cast<XPCWrappedNative*>(js::GetObjectPrivate(parentObj));
|
||||
rv = parentWrapper->RescueOrphans(ccx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now that we know our parent is in the right place, determine if we've
|
||||
// been orphaned. If not, we have nothing to do.
|
||||
if (!IsOrphan())
|
||||
|
@ -1551,150 +1551,33 @@ MoveableWrapperFinder(JSDHashTable *table, JSDHashEntryHdr *hdr,
|
||||
return JS_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
MoveWrapper(XPCCallContext& ccx, XPCWrappedNative *wrapper,
|
||||
XPCWrappedNativeScope *newScope, XPCWrappedNativeScope *oldScope)
|
||||
{
|
||||
// First, check to see if this wrapper really needs to be
|
||||
// reparented.
|
||||
|
||||
if (wrapper->GetScope() == newScope) {
|
||||
// The wrapper already got moved, nothing to do here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For performance reasons, we wait to fix up orphaned wrappers (wrappers
|
||||
// whose parents have moved to another scope) until right before they
|
||||
// threaten to confuse us.
|
||||
//
|
||||
// If this wrapper is an orphan, reunite it with its parent. If, following
|
||||
// that, the wrapper is no longer in the old scope, then we don't need to
|
||||
// reparent it.
|
||||
MOZ_ASSERT(wrapper->GetScope() == oldScope);
|
||||
nsresult rv = wrapper->RescueOrphans(ccx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (wrapper->GetScope() != oldScope)
|
||||
return NS_OK;
|
||||
|
||||
nsISupports *identity = wrapper->GetIdentityObject();
|
||||
nsCOMPtr<nsIClassInfo> info(do_QueryInterface(identity));
|
||||
|
||||
// ClassInfo is implemented as singleton objects. If the identity
|
||||
// object here is the same object as returned by the QI, then it
|
||||
// is the singleton classinfo, so we don't need to reparent it.
|
||||
if (SameCOMIdentity(identity, info))
|
||||
info = nullptr;
|
||||
|
||||
if (!info)
|
||||
return NS_OK;
|
||||
|
||||
XPCNativeScriptableCreateInfo sciProto;
|
||||
XPCNativeScriptableCreateInfo sci;
|
||||
const XPCNativeScriptableCreateInfo& sciWrapper =
|
||||
XPCWrappedNative::GatherScriptableCreateInfo(identity, info,
|
||||
sciProto, sci);
|
||||
|
||||
// If the wrapper doesn't want precreate, then we don't need to
|
||||
// worry about reparenting it.
|
||||
if (!sciWrapper.GetFlags().WantPreCreate())
|
||||
return NS_OK;
|
||||
|
||||
JSObject *newParent = oldScope->GetGlobalJSObject();
|
||||
rv = sciWrapper.GetCallback()->PreCreate(identity, ccx,
|
||||
newParent,
|
||||
&newParent);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (newParent == oldScope->GetGlobalJSObject()) {
|
||||
// The old scope still works for this wrapper. We have to
|
||||
// assume that the wrapper will continue to return the old
|
||||
// scope from PreCreate, so don't move it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// These are pretty special circumstances. Make sure that the parent here
|
||||
// is a bonafide WN with a proper parent chain.
|
||||
MOZ_ASSERT(!js::IsCrossCompartmentWrapper(newParent));
|
||||
MOZ_ASSERT(IS_WRAPPER_CLASS(js::GetObjectClass(newParent)));
|
||||
if (!IS_WN_WRAPPER_OBJECT(newParent))
|
||||
NS_ENSURE_STATE(MorphSlimWrapper(ccx, newParent));
|
||||
XPCWrappedNative *parentWrapper =
|
||||
static_cast<XPCWrappedNative*>(js::GetObjectPrivate(newParent));
|
||||
rv = parentWrapper->RescueOrphans(ccx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The wrapper returned a new parent. If the new parent is in a
|
||||
// different scope, then we need to reparent it, otherwise, the
|
||||
// old scope is fine.
|
||||
|
||||
XPCWrappedNativeScope *betterScope = parentWrapper->GetScope();
|
||||
if (betterScope == oldScope) {
|
||||
// The wrapper asked for a different object, but that object
|
||||
// was in the same scope. This means that the new parent
|
||||
// simply hasn't been reparented yet, so reparent it first,
|
||||
// and then continue reparenting the wrapper itself.
|
||||
|
||||
rv = MoveWrapper(ccx, parentWrapper, newScope, oldScope);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If the parent wanted to stay in the old scope, we have to stay with
|
||||
// it. This can happen when doing document.write when the old detached
|
||||
// about:blank document is still floating around in the scope. Leave it
|
||||
// behind to die.
|
||||
if (parentWrapper->GetScope() == oldScope)
|
||||
return NS_OK;
|
||||
NS_ASSERTION(parentWrapper->GetScope() == newScope,
|
||||
"A _third_ scope? Oh dear...");
|
||||
|
||||
} else
|
||||
NS_ASSERTION(betterScope == newScope, "Weird scope returned");
|
||||
|
||||
// Now, reparent the wrapper, since we know that it wants to be
|
||||
// reparented.
|
||||
|
||||
nsRefPtr<XPCWrappedNative> junk;
|
||||
rv = XPCWrappedNative::ReparentWrapperIfFound(ccx, oldScope,
|
||||
newScope, parentWrapper->GetFlatJSObject(),
|
||||
wrapper->GetIdentityObject(),
|
||||
getter_AddRefs(junk));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* void moveWrappers(in JSContextPtr aJSContext, in JSObjectPtr aOldScope, in JSObjectPtr aNewScope); */
|
||||
/* void rescueOrphansInScope(in JSContextPtr aJSContext, in JSObjectPtr aScope); */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::MoveWrappers(JSContext *aJSContext,
|
||||
JSObject *aOldScope,
|
||||
JSObject *aNewScope)
|
||||
nsXPConnect::RescueOrphansInScope(JSContext *aJSContext, JSObject *aScope)
|
||||
{
|
||||
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
|
||||
if (!ccx.IsValid())
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
XPCWrappedNativeScope *oldScope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, aOldScope);
|
||||
if (!oldScope)
|
||||
XPCWrappedNativeScope *scope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, aScope);
|
||||
if (!scope)
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
XPCWrappedNativeScope *newScope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, aNewScope);
|
||||
if (!newScope)
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
// First, look through the old scope and find all of the wrappers that
|
||||
// we're going to move.
|
||||
// First, look through the old scope and find all of the wrappers that we
|
||||
// might need to rescue.
|
||||
nsTArray<nsRefPtr<XPCWrappedNative> > wrappersToMove;
|
||||
|
||||
{ // scoped lock
|
||||
XPCAutoLock lock(GetRuntime()->GetMapLock());
|
||||
Native2WrappedNativeMap *map = oldScope->GetWrappedNativeMap();
|
||||
Native2WrappedNativeMap *map = scope->GetWrappedNativeMap();
|
||||
wrappersToMove.SetCapacity(map->Count());
|
||||
map->Enumerate(MoveableWrapperFinder, &wrappersToMove);
|
||||
}
|
||||
|
||||
// Now that we have the wrappers, reparent them to the new scope.
|
||||
for (uint32_t i = 0, stop = wrappersToMove.Length(); i < stop; ++i) {
|
||||
nsresult rv = MoveWrapper(ccx, wrappersToMove[i], newScope, oldScope);
|
||||
nsresult rv = wrappersToMove[i]->RescueOrphans(ccx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -2832,12 +2832,6 @@ public:
|
||||
nsISupports* aCOMObj,
|
||||
XPCWrappedNative** aWrapper);
|
||||
|
||||
// Returns the wrapper corresponding to the parent of our mFlatJSObject.
|
||||
//
|
||||
// If the parent does not have a WN, or if there is no parent, null is
|
||||
// returned.
|
||||
XPCWrappedNative *GetParentWrapper();
|
||||
|
||||
bool IsOrphan();
|
||||
nsresult RescueOrphans(XPCCallContext& ccx);
|
||||
|
||||
|
@ -2592,19 +2592,19 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
||||
if (GetAbsoluteCoord(styleMaxHeight, h) ||
|
||||
GetPercentHeight(styleMaxHeight, aFrame, h)) {
|
||||
h = NS_MAX(0, h - heightTakenByBoxSizing);
|
||||
nscoord maxHeight =
|
||||
nscoord maxWidth =
|
||||
NSToCoordRound(h * (float(ratio.width) / float(ratio.height)));
|
||||
if (maxHeight < result)
|
||||
result = maxHeight;
|
||||
if (maxWidth < result)
|
||||
result = maxWidth;
|
||||
}
|
||||
|
||||
if (GetAbsoluteCoord(styleMinHeight, h) ||
|
||||
GetPercentHeight(styleMinHeight, aFrame, h)) {
|
||||
h = NS_MAX(0, h - heightTakenByBoxSizing);
|
||||
nscoord minHeight =
|
||||
nscoord minWidth =
|
||||
NSToCoordRound(h * (float(ratio.width) / float(ratio.height)));
|
||||
if (minHeight > result)
|
||||
result = minHeight;
|
||||
if (minWidth > result)
|
||||
result = minWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8116,6 +8116,7 @@ DumpToPNG(nsIPresShell* shell, nsAString& name) {
|
||||
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
|
||||
rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
|
||||
outputStream, length);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t numWritten;
|
||||
rv = bufferedOutputStream->WriteFrom(encoder, length, &numWritten);
|
||||
|
@ -396,11 +396,16 @@ protected:
|
||||
bool ParseSelectorGroup(nsCSSSelectorList*& aListHead);
|
||||
bool ParseSelector(nsCSSSelectorList* aList, PRUnichar aPrevCombinator);
|
||||
|
||||
css::Declaration* ParseDeclarationBlock(bool aCheckForBraces);
|
||||
enum {
|
||||
eParseDeclaration_InBraces = 1 << 0,
|
||||
eParseDeclaration_AllowImportant = 1 << 1
|
||||
};
|
||||
|
||||
css::Declaration* ParseDeclarationBlock(uint32_t aFlags);
|
||||
bool ParseDeclaration(css::Declaration* aDeclaration,
|
||||
bool aCheckForBraces,
|
||||
bool aMustCallValueAppended,
|
||||
bool* aChanged);
|
||||
uint32_t aFlags,
|
||||
bool aMustCallValueAppended,
|
||||
bool* aChanged);
|
||||
|
||||
bool ParseProperty(nsCSSProperty aPropID);
|
||||
bool ParsePropertyByFunction(nsCSSProperty aPropID);
|
||||
@ -987,7 +992,12 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
|
||||
haveBraces = false;
|
||||
}
|
||||
|
||||
css::Declaration* declaration = ParseDeclarationBlock(haveBraces);
|
||||
uint32_t parseFlags = eParseDeclaration_AllowImportant;
|
||||
if (haveBraces) {
|
||||
parseFlags |= eParseDeclaration_InBraces;
|
||||
}
|
||||
|
||||
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
|
||||
if (declaration) {
|
||||
// Create a style rule for the declaration
|
||||
NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration));
|
||||
@ -1026,7 +1036,8 @@ CSSParserImpl::ParseDeclarations(const nsAString& aBuffer,
|
||||
for (;;) {
|
||||
// If we cleared the old decl, then we want to be calling
|
||||
// ValueAppended as we parse.
|
||||
if (!ParseDeclaration(aDeclaration, false, true, aChanged)) {
|
||||
if (!ParseDeclaration(aDeclaration, eParseDeclaration_AllowImportant,
|
||||
true, aChanged)) {
|
||||
if (!SkipDeclaration(false)) {
|
||||
break;
|
||||
}
|
||||
@ -2301,7 +2312,9 @@ CSSParserImpl::ParseKeyframeRule()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(true));
|
||||
// Ignore !important in keyframe rules
|
||||
uint32_t parseFlags = eParseDeclaration_InBraces;
|
||||
nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
|
||||
if (!declaration) {
|
||||
REPORT_UNEXPECTED(PEBadSelectorKeyframeRuleIgnored);
|
||||
return nullptr;
|
||||
@ -2757,7 +2770,9 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
|
||||
CLEAR_ERROR();
|
||||
|
||||
// Next parse the declaration block
|
||||
css::Declaration* declaration = ParseDeclarationBlock(true);
|
||||
uint32_t parseFlags = eParseDeclaration_InBraces |
|
||||
eParseDeclaration_AllowImportant;
|
||||
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
|
||||
if (nullptr == declaration) {
|
||||
delete slist;
|
||||
return false;
|
||||
@ -3877,9 +3892,11 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList,
|
||||
}
|
||||
|
||||
css::Declaration*
|
||||
CSSParserImpl::ParseDeclarationBlock(bool aCheckForBraces)
|
||||
CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags)
|
||||
{
|
||||
if (aCheckForBraces) {
|
||||
bool checkForBraces = (aFlags & eParseDeclaration_InBraces) != 0;
|
||||
|
||||
if (checkForBraces) {
|
||||
if (!ExpectSymbol('{', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEBadDeclBlockStart);
|
||||
OUTPUT_ERROR();
|
||||
@ -3891,12 +3908,11 @@ CSSParserImpl::ParseDeclarationBlock(bool aCheckForBraces)
|
||||
if (declaration) {
|
||||
for (;;) {
|
||||
bool changed;
|
||||
if (!ParseDeclaration(declaration, aCheckForBraces,
|
||||
true, &changed)) {
|
||||
if (!SkipDeclaration(aCheckForBraces)) {
|
||||
if (!ParseDeclaration(declaration, aFlags, true, &changed)) {
|
||||
if (!SkipDeclaration(checkForBraces)) {
|
||||
break;
|
||||
}
|
||||
if (aCheckForBraces) {
|
||||
if (checkForBraces) {
|
||||
if (ExpectSymbol('}', true)) {
|
||||
break;
|
||||
}
|
||||
@ -4281,10 +4297,12 @@ CSSParserImpl::ParseTreePseudoElement(nsAtomList **aPseudoElementArgs)
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
bool aCheckForBraces,
|
||||
uint32_t aFlags,
|
||||
bool aMustCallValueAppended,
|
||||
bool* aChanged)
|
||||
{
|
||||
bool checkForBraces = (aFlags & eParseDeclaration_InBraces) != 0;
|
||||
|
||||
mTempData.AssertInitialState();
|
||||
|
||||
// Get property name
|
||||
@ -4292,7 +4310,7 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
nsAutoString propertyName;
|
||||
for (;;) {
|
||||
if (!GetToken(true)) {
|
||||
if (aCheckForBraces) {
|
||||
if (checkForBraces) {
|
||||
REPORT_UNEXPECTED_EOF(PEDeclEndEOF);
|
||||
}
|
||||
return false;
|
||||
@ -4353,7 +4371,13 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
CLEAR_ERROR();
|
||||
|
||||
// Look for "!important".
|
||||
PriorityParsingStatus status = ParsePriority();
|
||||
PriorityParsingStatus status;
|
||||
if ((aFlags & eParseDeclaration_AllowImportant) != 0) {
|
||||
status = ParsePriority();
|
||||
}
|
||||
else {
|
||||
status = ePriority_None;
|
||||
}
|
||||
|
||||
// Look for a semicolon or close brace.
|
||||
if (status != ePriority_Error) {
|
||||
@ -4362,9 +4386,9 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
} else if (mToken.IsSymbol(';')) {
|
||||
// semicolon is always ok
|
||||
} else if (mToken.IsSymbol('}')) {
|
||||
// brace is ok if aCheckForBraces, but don't eat it
|
||||
// brace is ok if checkForBraces, but don't eat it
|
||||
UngetToken();
|
||||
if (!aCheckForBraces) {
|
||||
if (!checkForBraces) {
|
||||
status = ePriority_Error;
|
||||
}
|
||||
} else {
|
||||
@ -4374,7 +4398,7 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
}
|
||||
|
||||
if (status == ePriority_Error) {
|
||||
if (aCheckForBraces) {
|
||||
if (checkForBraces) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEBadDeclOrRuleEnd2);
|
||||
} else {
|
||||
REPORT_UNEXPECTED_TOKEN(PEBadDeclEnd);
|
||||
|
@ -1982,11 +1982,10 @@ nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
// constructs a rule node pointing to us in order to compute the
|
||||
// styles it needs to animate.
|
||||
|
||||
// FIXME (spec): The spec doesn't say what to do with !important.
|
||||
// We'll just map them.
|
||||
if (mDeclaration->HasImportantData()) {
|
||||
mDeclaration->MapImportantRuleInfoInto(aRuleData);
|
||||
}
|
||||
// The spec says that !important declarations should just be ignored
|
||||
NS_ASSERTION(!mDeclaration->HasImportantData(),
|
||||
"Keyframe rules has !important data");
|
||||
|
||||
mDeclaration->MapNormalRuleInfoInto(aRuleData);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user