Merge the last PGO-green inbound changeset to m-c.

This commit is contained in:
Ryan VanderMeulen 2012-10-16 21:52:06 -04:00
commit 9d8390c149
125 changed files with 1853 additions and 785 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -62,6 +62,7 @@ MOCHITEST_FILES := \
test_sequence_wrapping.html \
file_bug775543.html \
test_bug788369.html \
test_bug742191.html \
$(NULL)
MOCHITEST_CHROME_FILES = \

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@ -0,0 +1 @@
pref(media.peerconnection.enabled,true) load 791270.html

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -433,7 +433,7 @@ class IonBuilder : public MIRGenerator
void clearForBackEnd();
JSScript *script() const { return script_; }
Return<JSScript*> script() const { return script_; }
private:
JSContext *cx;

View File

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

View File

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

View File

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

View File

@ -29,6 +29,7 @@ class Linker
}
IonCode *newCode(JSContext *cx, IonCompartment *comp) {
AssertCanGC();
#ifndef JS_CPU_ARM
masm.flush();
#endif

View File

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

View File

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

View File

@ -510,6 +510,7 @@ template <class ArgSeq, class StoreOutputTo>
bool
CodeGeneratorShared::visitOutOfLineCallVM(OutOfLineCallVM<ArgSeq, StoreOutputTo> *ool)
{
AssertCanGC();
LInstruction *lir = ool->lir();
saveLive(lir);

View File

@ -386,6 +386,7 @@ IonCompartment::generateBailoutHandler(JSContext *cx)
IonCode *
IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
{
AssertCanGC();
typedef MoveResolver::MoveOperand MoveOperand;
JS_ASSERT(!StackKeptAligned);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 &regs)
{
/* 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 &regs)
TryNoteIter::TryNoteIter(const FrameRegs &regs)
: 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());

View File

@ -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 &regs = cx->regs();
if (IsOptimizedArguments(regs.fp(), &regs.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());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -143,6 +143,7 @@ class Assembler : public ValueAssembler
vmframe(vmframe),
pc(NULL)
{
AutoAssertNoGC nogc;
startLabel = label();
if (vmframe)
sps->setPushed(vmframe->script());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 &copy)
{
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 &regs = 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 &regs, 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 &regs, 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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