void FileReader::OnLoadEndArrayBuffer() { AutoJSAPI jsapi; if (!jsapi.Init(GetParentObject())) { FreeDataAndDispatchError(NS_ERROR_FAILURE); return; } RootResultArrayBuffer(); JSContext* cx = jsapi.cx(); mResultArrayBuffer = JS_NewArrayBufferWithContents(cx, mDataLen, mFileData); if (mResultArrayBuffer) { mFileData = nullptr; // Transfer ownership FreeDataAndDispatchSuccess(); return; } // Let's handle the error status. JS::Rooted<JS::Value> exceptionValue(cx); if (!JS_GetPendingException(cx, &exceptionValue) || // This should not really happen, exception should always be an object. !exceptionValue.isObject()) { JS_ClearPendingException(jsapi.cx()); FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY); return; } JS_ClearPendingException(jsapi.cx()); JS::Rooted<JSObject*> exceptionObject(cx, &exceptionValue.toObject()); JSErrorReport* er = JS_ErrorFromException(cx, exceptionObject); if (!er || er->message()) { FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY); return; } nsAutoString errorName; JSFlatString* name = js::GetErrorTypeName(cx, er->exnType); if (name) { AssignJSFlatString(errorName, name); } nsAutoCString errorMsg(er->message().c_str()); nsAutoCString errorNameC = NS_LossyConvertUTF16toASCII(errorName); // XXX Code selected arbitrarily mError = new DOMException(NS_ERROR_DOM_INVALID_STATE_ERR, errorMsg, errorNameC, DOMException_Binding::INVALID_STATE_ERR); FreeDataAndDispatchError(); }
/* void CompileFile (in nsILocalFile aFile, in PRBool strict); */ NS_IMETHODIMP nsXPCToolsCompiler::CompileFile(nsILocalFile *aFile, PRBool strict) { // use the xpccallcontext stuff to get the current JSContext // get the xpconnect service nsresult rv; nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); if(NS_FAILED(rv)) return NS_ERROR_FAILURE; // get the xpconnect native call context nsCOMPtr<nsIXPCNativeCallContext> callContext; xpc->GetCurrentNativeCallContext(getter_AddRefs(callContext)); if(!callContext) return NS_ERROR_FAILURE; // verify that we are being called from JS (i.e. the current call is // to this object - though we don't verify that it is to this exact method) nsCOMPtr<nsISupports> callee; callContext->GetCallee(getter_AddRefs(callee)); if(!callee || callee.get() != (nsISupports*)this) return NS_ERROR_FAILURE; // Get JSContext of current call JSContext* cx; rv = callContext->GetJSContext(&cx); if(NS_FAILED(rv) || !cx) return NS_ERROR_FAILURE; FILE* handle; if(NS_FAILED(aFile->OpenANSIFileDesc("r", &handle))) return NS_ERROR_FAILURE; JSObject* glob = JS_NewObject(cx, &global_class, NULL, NULL); if (!glob) return NS_ERROR_FAILURE; if (!JS_InitStandardClasses(cx, glob)) return NS_ERROR_FAILURE; nsCAutoString path; if(NS_FAILED(aFile->GetNativePath(path))) return NS_ERROR_FAILURE; uint32 oldoptions = JS_GetOptions(cx); JS_SetOptions(cx, JSOPTION_WERROR | (strict ? JSOPTION_STRICT : 0)); JSErrorReporter older = JS_SetErrorReporter(cx, ErrorReporter); JSExceptionState *es =JS_SaveExceptionState(cx); if(!JS_CompileFileHandle(cx, glob, path.get(), handle)) { jsval v; JSErrorReport* report; if(JS_GetPendingException(cx, &v) && nsnull != (report = JS_ErrorFromException(cx, v))) { JSString* str; const char* msg = "Error"; str = JS_ValueToString(cx, v); if(str) msg = JS_GetStringBytes(str); printf("%s [%s,%d]\n\n", msg, report->filename, (int)report->lineno); } else { printf("no script and no error report!\n"); } } JS_RestoreExceptionState(cx, es); JS_SetErrorReporter(cx, older); JS_SetOptions(cx, oldoptions); return NS_OK; }
nsresult WebCL_reportJSError (JSContext* cx, char const* aMsg, ...) { D_METHOD_START; nsresult rv = NS_OK; size_t sze = INITIAL_MSG_BUF_SIZE; char* msgBuf = NULL; va_list ap; while (true) { char* tmp = msgBuf; msgBuf = (char*)realloc (msgBuf, sze); if (!msgBuf) { if (tmp) free (tmp); return NS_ERROR_OUT_OF_MEMORY; } tmp = 0; va_start (ap, aMsg); int n = vsnprintf(msgBuf, sze, aMsg, ap); va_end (ap); if (n >= 0 && n < (int)sze) { // Successfull operation break; } else if (n > (int)sze) { // n more bytes needed for buffer sze = n + 1; } else if (n == -1) { // glibc 2.1 return -1 on truncate, grow the buffer and retry sze *= 2; } else { // Unexpected error occurred. D_LOG (LOG_LEVEL_WARNING, "Failed to format the message."); free (msgBuf); return NS_ERROR_FAILURE; } } nsCOMPtr<nsIXPConnect> xpc; JSBool ignored = JS_TRUE; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack; stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); if (NS_FAILED(rv)) goto done; cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } xpc = do_GetService (nsIXPConnect::GetCID (), &rv); if (NS_FAILED(rv)) goto done; JS_BeginRequest (cx); ignored = JS_EnterLocalRootScope (cx); (void)ignored; D_LOG (LOG_LEVEL_ERROR, "Reporting error to JS: \"%s\"", msgBuf); #if 1 JS_ReportError(cx, msgBuf); #else // JS_SetPendingException NOTE: caller must return with NS_OK or we'll just // get the usual MOZ exception msg { JSString *str = JS_NewStringCopyZ(cx, msgBuf); JS_SetPendingException (cx, STRING_TO_JSVAL(str)); JS_ReportPendingException (cx); //JSErrorReport* report = JS_ErrorFromException (cx, STRING_TO_JSVAL(str)); jsval expVal; if (JS_GetPendingException (cx, &expVal)) { JSErrorReport* report = JS_ErrorFromException (cx, expVal); fprintf(stderr, "report: %p\n", (void*)report); if (report) JS_ThrowReportedError (cx, "Fooooools!", report); } } // TODO: Figure out a way to throw real JS exceptions with // custom information. Currently, only generic XPCOM // error-generated exception is thrown and the error // message reported by this function is written on the // JS error console. #endif JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); done: free (msgBuf); return rv; }