mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Propagate compilation errors to our caller to make syntax errors easier to debug. bug 408412, r=shaver sr=brendan
This commit is contained in:
parent
d8801925e5
commit
0b0d6afb1e
@ -637,7 +637,8 @@ mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile,
|
||||
if (!entry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = GlobalForLocation(aComponentFile, &entry->global, &entry->location);
|
||||
rv = GlobalForLocation(aComponentFile, &entry->global, &entry->location,
|
||||
nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "GlobalForLocation failed!\n");
|
||||
@ -1060,7 +1061,8 @@ mozJSComponentLoader::WriteScript(nsIFastLoadService *flSvc, JSScript *script,
|
||||
nsresult
|
||||
mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
JSObject **aGlobal,
|
||||
char **aLocation)
|
||||
char **aLocation,
|
||||
jsval *exception)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -1190,22 +1192,37 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
// The script wasn't in the fastload cache, so compile it now.
|
||||
LOG(("Slow loading %s\n", nativePath.get()));
|
||||
|
||||
// If |exception| is non-null, then our caller wants to propagate any
|
||||
// exceptions out to our caller. Ensure that the engine doesn't
|
||||
// eagerly report the exception.
|
||||
uint32 oldopts = 0;
|
||||
if (exception) {
|
||||
oldopts = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_DONT_REPORT_UNCAUGHT);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PR_MEMMAP
|
||||
PRInt64 fileSize;
|
||||
rv = aComponent->GetFileSize(&fileSize);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt64 maxSize;
|
||||
LL_UI2L(maxSize, PR_UINT32_MAX);
|
||||
if (LL_CMP(fileSize, >, maxSize)) {
|
||||
NS_ERROR("file too large");
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PRFileDesc *fileHandle;
|
||||
rv = aComponent->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Make sure the file is closed, no matter how we return.
|
||||
FileAutoCloser fileCloser(fileHandle);
|
||||
@ -1214,6 +1231,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
PR_PROT_READONLY);
|
||||
if (!map) {
|
||||
NS_ERROR("Failed to create file map");
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1226,6 +1244,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
|
||||
if (!buf) {
|
||||
NS_WARNING("Failed to map file");
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1244,15 +1263,29 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
|
||||
FILE *fileHandle;
|
||||
rv = aComponent->OpenANSIFileDesc("r", &fileHandle);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
script = JS_CompileFileHandleForPrincipals(cx, global,
|
||||
nativePath.get(),
|
||||
fileHandle, jsPrincipals);
|
||||
|
||||
/* JS will close the filehandle after compilation is complete. */
|
||||
|
||||
#endif /* HAVE_PR_MEMMAP */
|
||||
|
||||
// Propagate the exception, if one exists. Also, don't leave the stale
|
||||
// exception on this context.
|
||||
// NB: The caller must stick exception into a rooted slot (probably on
|
||||
// its context) as soon as possible to avoid GC hazards.
|
||||
if (exception) {
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (!script) {
|
||||
JS_GetPendingException(cx, exception);
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!script) {
|
||||
@ -1474,14 +1507,27 @@ mozJSComponentLoader::ImportInto(const nsACString & aLocation,
|
||||
if (!newEntry || !mInProgressImports.Put(lfhash, newEntry))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
jsval exception = JSVAL_VOID;
|
||||
rv = GlobalForLocation(componentFile, &newEntry->global,
|
||||
&newEntry->location);
|
||||
&newEntry->location, &exception);
|
||||
|
||||
mInProgressImports.Remove(lfhash);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
*_retval = nsnull;
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
if (!JSVAL_IS_VOID(exception)) {
|
||||
// An exception was thrown during compilation. Propagate it
|
||||
// out to our caller so they can report it.
|
||||
JSContext *callercx;
|
||||
cc->GetJSContext(&callercx);
|
||||
JS_SetPendingException(callercx, exception);
|
||||
cc->SetExceptionWasThrown(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Something failed, but we don't know what it is, guess.
|
||||
return rv;
|
||||
}
|
||||
|
||||
mod = newEntry;
|
||||
|
@ -110,7 +110,8 @@ class mozJSComponentLoader : public nsIModuleLoader,
|
||||
|
||||
nsresult GlobalForLocation(nsILocalFile *aComponent,
|
||||
JSObject **aGlobal,
|
||||
char **location);
|
||||
char **location,
|
||||
jsval *exception);
|
||||
|
||||
nsresult StartFastLoad(nsIFastLoadService *flSvc);
|
||||
nsresult ReadScript(nsIFastLoadService *flSvc, const char *nativePath,
|
||||
|
1
js/src/xpconnect/tests/unit/syntax_error.jsm
Normal file
1
js/src/xpconnect/tests/unit/syntax_error.jsm
Normal file
@ -0,0 +1 @@
|
||||
bogusjs)(
|
51
js/src/xpconnect/tests/unit/test_bug408412.js
Normal file
51
js/src/xpconnect/tests/unit/test_bug408412.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Townsend <dtownsend@oxymoronical.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function run_test() {
|
||||
var file = do_get_file("js/src/xpconnect/tests/unit/syntax_error.jsm");
|
||||
var ios = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
var uri = ios.newFileURI(file);
|
||||
|
||||
try {
|
||||
Components.utils.import(uri.spec);
|
||||
do_throw("Failed to report any error at all");
|
||||
} catch (e) {
|
||||
do_check_neq(/^SyntaxError:/(e + ''), null);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user