void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorReport* report) { auto scope = getScope(cx); if (!JSREPORT_IS_WARNING(report->flags)) { str::stream ss; ss << message; // TODO: something far more elaborate that mimics the stack printing from v8 JS::RootedValue excn(cx); if (JS_GetPendingException(cx, &excn) && excn.isObject()) { JS::RootedValue stack(cx); ObjectWrapper(cx, excn).getValue("stack", &stack); auto str = ValueWriter(cx, stack).toString(); if (str.empty()) { ss << " @" << report->filename << ":" << report->lineno << ":" << report->column << "\n"; } else { ss << " :\n" << str; } } scope->_status = Status( JSErrorReportToStatus(cx, report, ErrorCodes::JSInterpreterFailure, message).code(), ss); } }
JSTrapStatus jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure) { JSDScript* jsdscript; JSDContext* jsdc = (JSDContext*) closure; JSD_ExecutionHookProc hook; void* hookData; if( ! jsdc || ! jsdc->inited ) return JSTRAP_CONTINUE; if( JSD_IS_DANGEROUS_THREAD(jsdc) ) return JSTRAP_CONTINUE; /* local in case jsdc->throwHook gets cleared on another thread */ JSD_LOCK(); hook = jsdc->throwHook; hookData = jsdc->throwHookData; JSD_UNLOCK(); if (!hook) return JSTRAP_CONTINUE; JSD_LOCK_SCRIPTS(jsdc); jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, JSNullFramePtr()); JSD_UNLOCK_SCRIPTS(jsdc); if( ! jsdscript ) return JSTRAP_CONTINUE; JS_GetPendingException(cx, rval); return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_THROW, hook, hookData, rval); }
void FFSessionHandler::getToStringTearOff(JSContext* ctx) { jsval funcVal; Debug::log(Debug::Debugging) << "Getting function \"__gwt_makeTearOff\"" << Debug::flush; if (!JS_GetProperty(ctx, global, "__gwt_makeTearOff", &funcVal) || funcVal == JSVAL_VOID) { Debug::log(Debug::Error) << "Could not get function \"__gwt_makeTearOff\"" << Debug::flush; return; } jsval jsargs[3] = { JSVAL_NULL, // no proxy INT_TO_JSVAL(InvokeMessage::TOSTRING_DISP_ID), // dispId JSVAL_ZERO // arg count is zero }; if (!JS_CallFunctionValue(ctx, global, funcVal, 3, jsargs, &toStringTearOff)) { jsval exc; if (JS_GetPendingException(ctx, &exc)) { Debug::log(Debug::Error) << "__gwt_makeTearOff(null,0,0) threw exception " << dumpJsVal(ctx, exc) << Debug::flush; } else { Debug::log(Debug::Error) << "Error creating toString tear-off" << Debug::flush; } // TODO(jat): show some crash page and die } }
JSBool gjs_move_exception(JSContext *src_context, JSContext *dest_context) { JSBool success; JS_BeginRequest(src_context); JS_BeginRequest(dest_context); /* NOTE: src and dest could be the same. */ jsval exc; if (JS_GetPendingException(src_context, &exc)) { if (src_context != dest_context) { /* try to add the current stack of dest_context to the * stack trace of exc */ try_to_chain_stack_trace(src_context, dest_context, exc); /* move the exception to dest_context */ JS_SetPendingException(dest_context, exc); JS_ClearPendingException(src_context); } success = JS_TRUE; } else { success = JS_FALSE; } JS_EndRequest(dest_context); JS_EndRequest(src_context); return success; }
bool ScriptInterface::ParseJSON(const std::string& string_utf8, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); std::wstring attrsW = wstring_from_utf8(string_utf8); utf16string string(attrsW.begin(), attrsW.end()); if (JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (u32)string.size(), out)) return true; LOGERROR("JS_ParseJSON failed!"); if (!JS_IsExceptionPending(m->m_cx)) return false; JS::RootedValue exc(m->m_cx); if (!JS_GetPendingException(m->m_cx, &exc)) return false; JS_ClearPendingException(m->m_cx); // We expect an object of type SyntaxError if (!exc.isObject()) return false; JS::RootedValue rval(m->m_cx); JS::RootedObject excObj(m->m_cx, &exc.toObject()); if (!JS_CallFunctionName(m->m_cx, excObj, "toString", JS::HandleValueArray::empty(), &rval)) return false; std::wstring error; ScriptInterface::FromJSVal(m->m_cx, rval, error); LOGERROR("%s", utf8_from_wstring(error)); return false; }
std::string CThreadDebugger::StringifyCyclicJSON(jsval obj, bool indent) { CyclicRefWorkaround::Stringifier str; CyclicRefWorkaround::g_ProcessedObjects.clear(); CyclicRefWorkaround::g_LastKey = JSVAL_VOID; JSObject* pGlob = JSVAL_TO_OBJECT(m->m_pScriptInterface->GetGlobalObject()); JSFunction* fun = JS_DefineFunction(m->m_pScriptInterface->GetContext(), pGlob, "replacer", CyclicRefWorkaround::replacer, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JSObject* replacer = JS_GetFunctionObject(fun); if (!JS_Stringify(m->m_pScriptInterface->GetContext(), &obj, replacer, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &CyclicRefWorkaround::Stringifier::callback, &str)) { LOGERROR(L"StringifyJSON failed"); jsval exec; jsval execString; if (JS_GetPendingException(m->m_pScriptInterface->GetContext(), &exec)) { if (JSVAL_IS_OBJECT(exec)) { JS_GetProperty(m->m_pScriptInterface->GetContext(), JSVAL_TO_OBJECT(exec), "message", &execString); if (JSVAL_IS_STRING(execString)) { std::string strExec = JS_EncodeString(m->m_pScriptInterface->GetContext(), JSVAL_TO_STRING(execString)); LOGERROR(L"Error: %hs", strExec.c_str()); } } } JS_ClearPendingException(m->m_pScriptInterface->GetContext()); return ""; } return str.stream.str(); }
jsval toval( const char * c ) { JSString * s = JS_NewStringCopyZ( _context , c ); if ( s ) return STRING_TO_JSVAL( s ); // possibly unicode, try manual size_t len = strlen( c ); size_t dstlen = len * 4; jschar * dst = (jschar*)malloc( dstlen ); JSBool res = JS_DecodeBytes( _context , c , len , dst, &dstlen ); if ( res ) { s = JS_NewUCStringCopyN( _context , dst , dstlen ); } free( dst ); if ( ! res ) { cout << "decode failed. probably invalid utf-8 string [" << c << "]" << endl; jsval v; if ( JS_GetPendingException( _context , &v ) ) cout << "\t why: " << toString( v ) << endl; throw UserException( 9006 , "invalid utf8" ); } assert( s ); return STRING_TO_JSVAL( s ); }
void Promise::HandleException(JSContext* aCx) { JS::Rooted<JS::Value> exn(aCx); if (JS_GetPendingException(aCx, &exn)) { JS_ClearPendingException(aCx); // This is only called from MaybeSomething, so it's OK to MaybeReject here. MaybeReject(aCx, exn); } }
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(); }
// PD_TRACE_DECLARE_FUNCTION ( SDB_SCOPE_EVALUATE2, "Scope::evaluate2" ) INT32 Scope::evaluate2 ( const CHAR *code, UINT32 len, UINT32 lineno, jsval *rval, CHAR **errMsg, INT32 printFlag ) { PD_TRACE_ENTRY ( SDB_SCOPE_EVALUATE2 ); INT32 rc = SDB_OK ; jsval exception = JSVAL_VOID ; CHAR *cstrException = NULL ; SDB_ASSERT ( _context && _global, "this scope has not been initilized" ) ; SDB_ASSERT ( code , "Invalid arguments" ) ; // set error report sdbSetPrintError( ( printFlag & SPT_EVAL_FLAG_PRINT ) ? TRUE : FALSE ) ; sdbSetNeedClearErrorInfo( TRUE ) ; if ( ! JS_EvaluateScript ( _context, _global, code, len, NULL, lineno, rval ) ) { rc = sdbGetErrno() ? sdbGetErrno() : SDB_SPT_EVAL_FAIL ; goto error ; } // clear return error if ( sdbIsNeedClearErrorInfo() && !JS_IsExceptionPending( _context ) ) { sdbClearErrorInfo() ; } done: PD_TRACE_EXITRC ( SDB_SCOPE_EVALUATE2, rc ); return rc ; error: if ( JS_IsExceptionPending( _context ) && JS_GetPendingException ( _context , &exception ) ) { cstrException = convertJsvalToString ( _context , exception ) ; if ( cstrException ) { if ( printFlag & SPT_EVAL_FLAG_PRINT ) { ossPrintf ( "Uncaught exception: %s\n" , cstrException ) ; } /// what to do when oom? *errMsg = ossStrdup( cstrException ) ; SAFE_JS_FREE ( _context , cstrException ) ; } else { JS_ClearPendingException ( _context ) ; } } goto done ; }
bool ToJSValue(JSContext* aCx, ErrorResult& aArgument, JS::MutableHandle<JS::Value> aValue) { MOZ_ASSERT(aArgument.Failed()); MOZ_ASSERT( !aArgument.IsUncatchableException(), "Doesn't make sense to convert uncatchable exception to a JS value!"); MOZ_ALWAYS_TRUE(aArgument.MaybeSetPendingException(aCx)); MOZ_ALWAYS_TRUE(JS_GetPendingException(aCx, aValue)); JS_ClearPendingException(aCx); return true; }
static JSBool DriverManager_getConnection(JSContext *cx, unsigned argc, jsval *vp) { jsval drivers; JS_LookupProperty(cx, JS_THIS_OBJECT(cx, vp), "drivers", &drivers); // FIXME check return code; check that drivers is an array JSObject *obj = JSVAL_TO_OBJECT(drivers); uint32_t len, i; JS_GetArrayLength(cx, obj, &len); jsval connect_argv[2] = {JS_ARGV(cx, vp)[0]}; if (argc == 2) { /* Caller passed "info" object, so we forward it as-is */ connect_argv[1] = JS_ARGV(cx, vp)[1]; } else { JSObject *info = JS_NewObject(cx, NULL, NULL, NULL); // FIXME root it to avoid GC if (argc > 1) JS_DefineProperty(cx, info, "user", JS_ARGV(cx, vp)[1], NULL, NULL, JSPROP_ENUMERATE); if (argc > 2) JS_DefineProperty(cx, info, "password", JS_ARGV(cx, vp)[2], NULL, NULL, JSPROP_ENUMERATE); connect_argv[1] = OBJECT_TO_JSVAL(info); }; jsval reason = JSVAL_NULL; for (i = 0; i < len; i++) { jsval driver, rval; JS_GetElement(cx, obj, i, &driver); if (!JS_CallFunctionName(cx, JSVAL_TO_OBJECT(driver), "connect", 2, &connect_argv[0], &rval)) { if (JSVAL_IS_NULL(reason)) JS_GetPendingException(cx, &reason); continue; } if (JSVAL_IS_NULL(rval)) continue; JS_SET_RVAL(cx, vp, rval); return JS_TRUE; } if (JSVAL_IS_NULL(reason)) { JSString *url_str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]); // FIXME check return value // FIXME root url_str (protect from GC) -> https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_ValueToString char *url = JS_EncodeString(cx, url_str); JS_ReportError(cx, "No suitable driver found for %s", url); JS_free(cx, url); } else JS_SetPendingException(cx, reason); JS_SET_RVAL(cx, vp, JSVAL_NULL); return JS_FALSE; }
static JSBool enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { JSObject *iterator; switch (enum_op) { case JSENUMERATE_INIT: if (resolverHasMethod(cx, obj, "enumerate")) { if (!delegateToResolver(cx, obj, "enumerate", 0, NULL, statep)) return JS_FALSE; if (!JSVAL_IS_OBJECT(*statep)) { JS_ReportError(cx, "Expected enumerate() to return an iterator."); return JS_FALSE; } *idp = JSVAL_ZERO; JS_AddRoot(cx, statep); return JS_TRUE; } // TODO: Default behavior? JS_ReportError(cx, "Enumeration is not implemented on this object."); return JS_FALSE; case JSENUMERATE_NEXT: jsval rval; iterator = JSVAL_TO_OBJECT(*statep); if (!JS_CallFunctionName(cx, iterator, "next", 0, NULL, &rval)) { if (JS_IsExceptionPending(cx)) { jsval exception; if (!JS_GetPendingException(cx, &exception)) return JS_FALSE; if (!JSVAL_IS_OBJECT(exception)) return JS_FALSE; JSClass *clasp = JS_GET_CLASS(cx, JSVAL_TO_OBJECT(exception)); if (clasp && JSCLASS_CACHED_PROTO_KEY(clasp) == JSProto_StopIteration) { JS_ClearPendingException(cx); *statep = JSVAL_NULL; JS_RemoveRoot(cx, statep); return JS_TRUE; } } return JS_FALSE; } if (!JS_ValueToId(cx, rval, idp)) return JS_FALSE; return JS_TRUE; case JSENUMERATE_DESTROY: JS_RemoveRoot(cx, statep); return JS_TRUE; default: JS_ReportError(cx, "Unknown enum_op"); return JS_FALSE; } }
bool AutoJSAPI::PeekException(JS::MutableHandle<JS::Value> aVal) { MOZ_ASSERT_IF(mIsMainThread, CxPusherIsStackTop()); MOZ_ASSERT(HasException()); MOZ_ASSERT(js::GetContextCompartment(cx())); if (!JS_GetPendingException(cx(), aVal)) { return false; } return true; }
JSBool js_ReportUncaughtException(JSContext *cx) { JSObject *exnObject; JSString *str; jsval exn; JSErrorReport *reportp; const char *bytes; if (!JS_IsExceptionPending(cx)) return JS_FALSE; if (!JS_GetPendingException(cx, &exn)) return JS_FALSE; /* * Because js_ValueToString below could error and an exception object * could become unrooted, we root it here. */ if (JSVAL_IS_OBJECT(exn) && exn != JSVAL_NULL) { exnObject = JSVAL_TO_OBJECT(exn); if (!js_AddRoot(cx, &exnObject, "exn.report.root")) return JS_FALSE; } else { exnObject = NULL; } #if JS_HAS_ERROR_EXCEPTIONS reportp = js_ErrorFromException(cx, exn); #else reportp = NULL; #endif str = js_ValueToString(cx, exn); bytes = str ? js_GetStringBytes(str) : "null"; if (reportp == NULL) { /* * XXXmccabe todo: Instead of doing this, synthesize an error report * struct that includes the filename, lineno where the exception was * originally thrown. */ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNCAUGHT_EXCEPTION, bytes); } else { /* Flag the error as an exception. */ reportp->flags |= JSREPORT_EXCEPTION; js_ReportErrorAgain(cx, bytes, reportp); } if (exnObject != NULL) js_RemoveRoot(cx->runtime, &exnObject); return JS_TRUE; }
bool AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal) { MOZ_ASSERT(CxPusherIsStackTop()); MOZ_ASSERT(HasException()); MOZ_ASSERT(js::GetContextCompartment(cx())); if (!JS_GetPendingException(cx(), aVal)) { return false; } JS_ClearPendingException(cx()); return true; }
JSDValue* jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate) { JSContext* cx; jsval val; if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate))) return NULL; if(JS_GetPendingException(cx, &val)) return jsd_NewValue(jsdc, val); return NULL; }
bool ToJSValue(JSContext* aCx, ErrorResult& aArgument, JS::MutableHandle<JS::Value> aValue) { MOZ_ASSERT(aArgument.Failed()); MOZ_ASSERT(!aArgument.IsUncatchableException(), "Doesn't make sense to convert uncatchable exception to a JS value!"); AutoForceSetExceptionOnContext forceExn(aCx); DebugOnly<bool> throwResult = aArgument.MaybeSetPendingException(aCx); MOZ_ASSERT(throwResult); DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue); MOZ_ASSERT(getPendingResult); JS_ClearPendingException(aCx); return true; }
JSTrapStatus CThreadDebugger::ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval) { jsval jsexception; JS_GetPendingException(cx, &jsexception); if (JSVAL_IS_STRING(jsexception)) { std::string str(JS_EncodeString(cx, JSVAL_TO_STRING(jsexception))); if (str == "Breakpoint" || m->m_pDebuggingServer->GetSettingBreakOnException()) { if (str == "Breakpoint") JS_ClearPendingException(cx); jsval val = JSVAL_NULL; return BreakHandler(cx, script, pc, rval, val, BREAK_SRC_EXCEPTION); } } return JSTRAP_CONTINUE; }
// callback for JS_SetErrorReporter static void report_js_error(JSContext* js, const char* message, JSErrorReport* UNUSED(report)) { // first we find ourselves VALUE self = (VALUE)JS_GetContextPrivate(js); // then we find our bridge JohnsonContext* context; Data_Get_Struct(self, JohnsonContext, context); // NOTE: SpiderMonkey REALLY doesn't like being interrupted. If we // jump over to Ruby and raise here, segfaults and such ensue. // Instead, we store the exception (if any) and the error message // on the context. They're dealt with in the if (!ok) block of evaluate(). strncpy(context->msg, message, MAX_EXCEPTION_MESSAGE_SIZE); JS_GetPendingException(context->js, &context->ex); }
~AutoPACErrorReporter() { if (!JS_IsExceptionPending(mCx)) { return; } JS::RootedValue exn(mCx); if (!JS_GetPendingException(mCx, &exn)) { return; } JS_ClearPendingException(mCx); js::ErrorReport report(mCx); if (!report.init(mCx, exn, js::ErrorReport::WithSideEffects)) { JS_ClearPendingException(mCx); return; } PACLogErrorOrWarning(NS_LITERAL_STRING("Error"), report.report()); }
static void try_to_chain_stack_trace(JSContext *src_context, JSContext *dst_context, jsval src_exc) { /* append current stack of dst_context to stack trace for src_exc. * we bail if anything goes wrong, just using the src_exc unmodified * in that case. */ jsval chained, src_stack, dst_stack, new_stack; JSString *new_stack_str; JS_BeginRequest(src_context); JS_BeginRequest(dst_context); if (!JSVAL_IS_OBJECT(src_exc)) goto out; // src_exc doesn't have a stack trace /* create a new exception in dst_context to get a stack trace */ gjs_throw_literal(dst_context, "Chained exception"); if (!(JS_GetPendingException(dst_context, &chained) && JSVAL_IS_OBJECT(chained))) goto out; // gjs_throw_literal didn't work?! JS_ClearPendingException(dst_context); /* get stack trace for src_exc and chained */ if (!(gjs_object_get_property(dst_context, JSVAL_TO_OBJECT(chained), "stack", &dst_stack) && JSVAL_IS_STRING(dst_stack))) goto out; // couldn't get chained stack if (!(gjs_object_get_property(src_context, JSVAL_TO_OBJECT(src_exc), "stack", &src_stack) && JSVAL_IS_STRING(src_stack))) goto out; // couldn't get source stack /* add chained exception's stack trace to src_exc */ new_stack_str = JS_ConcatStrings (dst_context, JSVAL_TO_STRING(src_stack), JSVAL_TO_STRING(dst_stack)); if (new_stack_str==NULL) goto out; // couldn't concatenate src and dst stacks?! new_stack = STRING_TO_JSVAL(new_stack_str); JS_SetProperty(dst_context, JSVAL_TO_OBJECT(src_exc), "stack", &new_stack); out: JS_EndRequest(dst_context); JS_EndRequest(src_context); }
already_AddRefed<IDBTransaction> IDBDatabase::Transaction(const StringOrStringSequence& aStoreNames, IDBTransactionMode aMode, ErrorResult& aRv) { AssertIsOnOwningThread(); aRv.MightThrowJSException(); if (aMode == IDBTransactionMode::Readwriteflush && !IndexedDatabaseManager::ExperimentalFeaturesEnabled()) { // Pretend that this mode doesn't exist. We don't have a way to annotate // certain enum values as depending on preferences so we just duplicate the // normal exception generation here. ThreadsafeAutoJSContext cx; // Disable any automatic error reporting that might be set up so that we // can grab the exception object. AutoForceSetExceptionOnContext forceExn(cx); MOZ_ALWAYS_FALSE( ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, "Argument 2 of IDBDatabase.transaction", "readwriteflush", "IDBTransactionMode")); MOZ_ASSERT(JS_IsExceptionPending(cx)); JS::Rooted<JS::Value> exception(cx); MOZ_ALWAYS_TRUE(JS_GetPendingException(cx, &exception)); aRv.ThrowJSException(cx, exception); return nullptr; } RefPtr<IDBTransaction> transaction; aRv = Transaction(aStoreNames, aMode, getter_AddRefs(transaction)); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } return transaction.forget(); }
bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool assertOnError) { if (success) return false; if (_quickExit) return false; if (_status.isOK()) { JS::RootedValue excn(_context); if (JS_GetPendingException(_context, &excn) && excn.isObject()) { str::stream ss; JS::RootedValue stack(_context); ObjectWrapper(_context, excn).getValue("stack", &stack); ss << ValueWriter(_context, excn).toString() << " :\n" << ValueWriter(_context, stack).toString(); _status = Status(ErrorCodes::JSInterpreterFailure, ss); } else { _status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter"); } } _error = _status.reason(); if (reportError) error() << _error << std::endl; // Clear the status state auto status = std::move(_status); if (assertOnError) { // Throw if necessary uassertStatusOK(status); } return true; }
/* * call-seq: * evaluate_compiled_script(script) * * Evaluate +script+ */ static VALUE evaluate_compiled_script(VALUE self, VALUE compiled_script) { JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonRuntime, runtime); JSContext * context = johnson_get_current_context(runtime); JohnsonContext * johnson_context = OUR_CONTEXT(context); // clean things up first johnson_context->ex = 0; memset(johnson_context->msg, 0, MAX_EXCEPTION_MESSAGE_SIZE); jsval compiled_js; if(!convert_to_js(runtime, compiled_script, &compiled_js)) rb_raise(rb_eRuntimeError, "Script compilation failed"); JSScript * js_script = (JSScript *)JS_GetPrivate(context, JSVAL_TO_OBJECT(compiled_js)); jsval js; JSBool ok = JS_ExecuteScript(context, runtime->global, js_script, &js); if (!ok) { if (JS_IsExceptionPending(context)) { // If there's an exception pending here, it's a syntax error. JS_GetPendingException(context, &johnson_context->ex); JS_ClearPendingException(context); } if (johnson_context->ex) { RAISE_JS_ERROR(self, johnson_context->ex); return Qnil; } } return convert_to_ruby(runtime, js); }
void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorReport* report) { auto scope = getScope(cx); if (!JSREPORT_IS_WARNING(report->flags)) { str::stream ss; ss << message; // TODO: something far more elaborate that mimics the stack printing from v8 JS::RootedValue excn(cx); if (JS_GetPendingException(cx, &excn) && excn.isObject()) { JS::RootedValue stack(cx); ObjectWrapper(cx, excn).getValue("stack", &stack); ss << " :\n" << ValueWriter(cx, stack).toString(); } scope->_status = Status(report->errorNumber ? static_cast<ErrorCodes::Error>(report->errorNumber) : ErrorCodes::JSInterpreterFailure, ss); } }
NORETURN(void) raise_js_error_in_ruby(JohnsonRuntime* runtime) { JSContext * context = johnson_get_current_context(runtime); JohnsonContext * johnson_context = OUR_CONTEXT(context); if (JS_IsExceptionPending(context)) { assert(JS_GetPendingException(context, &(johnson_context->ex))); JS_AddNamedRoot(context, &(johnson_context->ex), "raise_js_error_in_ruby"); JS_ClearPendingException(context); JS_RemoveRoot(context, &(johnson_context->ex)); } VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js); if (johnson_context->ex) RAISE_JS_ERROR(ruby_runtime, johnson_context->ex); // FIXME: I don't think this is needed, it should // be done on the Ruby side. if (!johnson_context->msg) rb_raise(rb_eRuntimeError, "Unknown JavaScriptError"); // FIXME: I don't think this can ever happen.... rb_raise(rb_eRuntimeError, johnson_context->msg); }
/* * call-seq: * native_compile(script, filename, linenum) * * Compile +script+ with +filename+ using +linenum+ */ static VALUE native_compile(VALUE self, VALUE script, VALUE filename, VALUE linenum) { JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonRuntime, runtime); JSContext * context = johnson_get_current_context(runtime); JohnsonContext * johnson_context = OUR_CONTEXT(context); JSScript * compiled_js = JS_CompileScript( context, runtime->global, StringValuePtr(script), (size_t)StringValueLen(script), StringValueCStr(filename), (unsigned)NUM2INT(linenum) ); if(compiled_js == NULL) { if (JS_IsExceptionPending(context)) { // If there's an exception pending here, it's a syntax error. JS_GetPendingException(context, &johnson_context->ex); JS_ClearPendingException(context); } if (johnson_context->ex) { RAISE_JS_ERROR(self, johnson_context->ex); return Qnil; } } JSObject * script_object = JS_NewScriptObject(context, compiled_js); PREPARE_RUBY_JROOTS(context, 1); JROOT(script_object); JRETURN_RUBY(make_ruby_land_proxy(runtime, OBJECT_TO_JSVAL(script_object), "JSScriptProxy")); }
JSDProperty* jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name) { JSContext* cx = jsdc->dumbContext; JSDProperty* jsdprop; JSDProperty* iter = NULL; JSObject* obj; uintN attrs = 0; JSBool found; JSPropertyDesc pd; const jschar * nameChars; size_t nameLen; jsval val, nameval; jsid nameid; JSCrossCompartmentCall *call = NULL; if(!jsd_IsValueObject(jsdc, jsdval)) return NULL; /* If we already have the prop, then return it */ while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter))) { JSString* propName = jsd_GetValueString(jsdc, jsdprop->name); if(propName) { intN result; if (JS_CompareStrings(cx, propName, name, &result) && !result) return jsdprop; } JSD_DropProperty(jsdc, jsdprop); } /* Not found in property list, look it up explicitly */ if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen))) return NULL; JS_BeginRequest(cx); call = JS_EnterCrossCompartmentCall(cx, obj); if(!call) { JS_EndRequest(cx); return NULL; } JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found); if (!found) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } JS_ClearPendingException(cx); if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val)) { if (JS_IsExceptionPending(cx)) { if (!JS_GetPendingException(cx, &pd.value)) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } pd.flags = JSPD_EXCEPTION; } else { pd.flags = JSPD_ERROR; pd.value = JSVAL_VOID; } } else { pd.value = val; } JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); nameval = STRING_TO_JSVAL(name); if (!JS_ValueToId(cx, nameval, &nameid) || !JS_IdToValue(cx, nameid, &pd.id)) { return NULL; } pd.slot = pd.spare = 0; pd.alias = JSVAL_NULL; pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0 | (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0 | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0; return _newProperty(jsdc, &pd, JSDPD_HINTED); }
// PD_TRACE_DECLARE_FUNCTION ( SDB_SCOPE_EVALUATE, "Scope::evaluate" ) INT32 Scope::evaluate ( const CHAR *code , UINT32 len, const CHAR *filename, UINT32 lineno, CHAR ** result, INT32 printFlag ) { PD_TRACE_ENTRY ( SDB_SCOPE_EVALUATE ); jsval rval = JSVAL_VOID ; jsval exception = JSVAL_VOID ; CHAR * cstrException = NULL ; CHAR * cstr = NULL ; INT32 rc = SDB_OK ; SDB_ASSERT ( _context && _global, "this scope has not been initilized" ) ; SDB_ASSERT ( code , "Invalid arguments" ) ; // set error report sdbSetPrintError( ( printFlag & SPT_EVAL_FLAG_PRINT ) ? TRUE : FALSE ) ; sdbSetNeedClearErrorInfo( TRUE ) ; if ( ! JS_EvaluateScript ( _context , _global , code , len > 0 ? len : ossStrlen ( code ) , filename ? filename : "(default)" , lineno , &rval ) ) { rc = sdbGetErrno() ? sdbGetErrno() : SDB_SPT_EVAL_FAIL ; ; goto error ; } // clear return error if ( sdbIsNeedClearErrorInfo() && !JS_IsExceptionPending( _context ) ) { sdbClearErrorInfo() ; } if ( !result ) { goto done ; } // cstr is freed in done: // cstr is freed by JSFree, so we have to use strdup instead of ossStrdup if ( JSVAL_IS_VOID ( rval ) ) { #if defined (_LINUX) cstr = strdup ( "" ) ; #elif defined (_WINDOWS) cstr = _strdup ( "" ) ; #endif } else { cstr = convertJsvalToString ( _context , rval ) ; } if ( ! cstr ) { rc = SDB_SYS ; goto error ; } *result = ossStrdup ( cstr ) ; if ( !( result && result[0] != '\0') ) { rc = SDB_OOM ; PD_LOG ( PDERROR , "memory allcation fail" ) ; goto error ; } done : SAFE_JS_FREE ( _context , cstr ) ; PD_TRACE_EXITRC ( SDB_SCOPE_EVALUATE, rc ); return rc ; error : if ( JS_GetPendingException ( _context , &exception ) ) { cstrException = convertJsvalToString ( _context , exception ) ; if ( cstrException ) { if ( printFlag & SPT_EVAL_FLAG_PRINT ) { ossPrintf ( "Uncaught exception: %s\n" , cstrException ) ; } SAFE_JS_FREE ( _context , cstrException ) ; } else { JS_ClearPendingException ( _context ) ; } } goto done ; }