| // Copyright 2016 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| #include "cobalt/script/mozjs/mozjs_exception_state.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/logging.h" |
| #include "base/string_number_conversions.h" |
| #include "base/string_util.h" |
| #include "cobalt/script/mozjs/conversion_helpers.h" |
| #include "third_party/mozjs/js/src/jsexn.h" |
| |
| namespace cobalt { |
| namespace script { |
| namespace mozjs { |
| |
| namespace { |
| |
| JSExnType ConvertToMozjsExceptionType(SimpleExceptionType type) { |
| switch (type) { |
| case kError: |
| return JSEXN_ERR; |
| case kTypeError: |
| return JSEXN_TYPEERR; |
| case kRangeError: |
| return JSEXN_RANGEERR; |
| case kReferenceError: |
| return JSEXN_REFERENCEERR; |
| case kSyntaxError: |
| return JSEXN_SYNTAXERR; |
| case kURIError: |
| return JSEXN_URIERR; |
| } |
| NOTREACHED(); |
| return JSEXN_ERR; |
| } |
| |
| // JSErrorCallback. |
| const JSErrorFormatString* GetErrorMessage(void* user_ref, const char* locale, |
| const unsigned error_number) { |
| return static_cast<JSErrorFormatString*>(user_ref); |
| } |
| |
| } // namespace |
| |
| void MozjsExceptionState::SetException( |
| const scoped_refptr<ScriptException>& exception) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(!is_exception_set_); |
| |
| MozjsGlobalEnvironment* global_environment = |
| static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context_)); |
| |
| JS::RootedObject exception_object( |
| context_, |
| global_environment->wrapper_factory()->GetWrapperProxy(exception)); |
| JS::RootedValue exception_value(context_, OBJECT_TO_JSVAL(exception_object)); |
| JS_SetPendingException(context_, exception_value); |
| |
| is_exception_set_ = true; |
| } |
| |
| void MozjsExceptionState::SetSimpleExceptionVA(SimpleExceptionType type, |
| const char* format, |
| va_list arguments) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(!is_exception_set_); |
| |
| std::string error_message = base::StringPrintV(format, arguments); |
| JSErrorFormatString format_string; |
| format_string.format = error_message.c_str(); |
| // Already fed arguments for format. |
| format_string.argCount = 0; |
| format_string.exnType = ConvertToMozjsExceptionType(type); |
| |
| // This function creates a JSErrorReport, populate it with an error message |
| // obtained from the given JSErrorCallback. The resulting error message is |
| // passed to the context's JSErrorReporter callback. |
| JS_ReportErrorNumber(context_, GetErrorMessage, |
| static_cast<void*>(&format_string), type); |
| is_exception_set_ = true; |
| } |
| |
| JSObject* MozjsExceptionState::CreateErrorObject(JSContext* context, |
| SimpleExceptionType type) { |
| JSExnType mozjs_type = ConvertToMozjsExceptionType(type); |
| JS::RootedObject error_prototype(context); |
| if (!JS_GetClassPrototype(context, GetExceptionProtoKey(mozjs_type), |
| error_prototype.address())) { |
| DLOG(ERROR) << "Failed to get Error prototype."; |
| return NULL; |
| } |
| return JS_NewObject(context, NULL, error_prototype, NULL); |
| } |
| |
| } // namespace mozjs |
| } // namespace script |
| } // namespace cobalt |