blob: ab6387dae865468fd5e02f608a6e87019829182a [file] [log] [blame]
// 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