blob: 13a0fd4040e4070729b9518bf551625a36edef1e [file] [log] [blame]
// Copyright 2017 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.
#ifndef COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
#define COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
#include <limits>
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/optional.h"
#include "base/stringprintf.h"
#include "cobalt/base/compiler.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/token.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/union_type_conversion_forward.h"
#include "cobalt/script/v8c/v8c_callback_interface_holder.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "cobalt/script/v8c/v8c_user_object_holder.h"
#include "cobalt/script/v8c/v8c_value_handle.h"
#include "cobalt/script/value_handle.h"
#include "nb/memory_scope.h"
#include "v8/include/v8.h"
namespace cobalt {
namespace script {
namespace v8c {
// Flags that can be used as a bitmask for special conversion behaviour.
enum ConversionFlags {
kNoConversionFlags = 0,
kConversionFlagRestricted = 1 << 0,
kConversionFlagNullable = 1 << 1,
kConversionFlagTreatNullAsEmptyString = 1 << 2,
kConversionFlagTreatUndefinedAsEmptyString = 1 << 3,
kConversionFlagClamped = 1 << 4,
kConversionFlagObjectOnly = 1 << 5,
// Valid conversion flags for numeric values.
kConversionFlagsNumeric = kConversionFlagRestricted | kConversionFlagClamped,
// Valid conversion flags for string types.
kConversionFlagsString = kConversionFlagTreatNullAsEmptyString |
kConversionFlagTreatUndefinedAsEmptyString,
// Valid conversion flags for objects.
kConversionFlagsObject = kConversionFlagNullable,
// Valid conversion flags for ValueHandles.
kConversionFlagsValueHandle =
kConversionFlagObjectOnly | kConversionFlagNullable,
// Valid conversion flags for callback functions.
kConversionFlagsCallbackFunction = kConversionFlagNullable,
// Valid conversion flags for callback interfaces.
kConversionFlagsCallbackInterface = kConversionFlagNullable,
};
// std::string -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const std::string& in_string,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// JSValue -> std::string
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
std::string* out_string);
// std::vector<uint8_t> -> JSValue
// Note that this conversion is specifically for the Web IDL type ByteString.
// Ideally, conversion requests would be explicit in what type they wanted to
// convert to, however it is currently solely based on input type.
inline void ToJSValue(v8::Isolate* isolate, const std::vector<uint8_t>& in_data,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// base::Token -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const base::Token& token,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// bool -> JSValue
inline void ToJSValue(v8::Isolate* isolate, bool in_boolean,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// JSValue -> bool
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
bool* out_boolean) {
NOTIMPLEMENTED();
}
// signed integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed &&
(sizeof(T) <= 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
template <typename T>
inline const double UpperBound() {
return std::numeric_limits<T>::max();
}
template <typename T>
inline const double LowerBound() {
return std::numeric_limits<T>::min();
}
// The below specializations of UpperBound<T> and LowerBound<T> for 64
// bit integers use the (2^(53) - 1) and similar bounds specified in
// step 1 of ConvertToInt, see:
// https://heycam.github.io/webidl/#abstract-opdef-converttoint
template <>
inline const double UpperBound<int64_t>() {
const double kInt64UpperBound = static_cast<double>((1ll << 53) - 1);
return kInt64UpperBound;
}
template <>
inline const double LowerBound<int64_t>() {
const double kInt64LowerBound = static_cast<double>(-(1ll << 53) + 1);
return kInt64LowerBound;
}
template <>
inline const double UpperBound<uint64_t>() {
const double kUInt64UpperBound = static_cast<double>((1ll << 53) - 1);
return kUInt64UpperBound;
}
template <typename T>
void ClampedValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
v8::Local<v8::Value>* clamped_value) {
NOTIMPLEMENTED();
}
// JSValue -> signed integers <= 4 bytes
template <typename T>
inline void FromJSValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
ExceptionState* exception_state, T* out_number,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed &&
(sizeof(T) <= 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// JSValue -> signed integers > 4 bytes
template <typename T>
inline void FromJSValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
ExceptionState* exception_state, T* out_number,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed &&
(sizeof(T) > 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// signed integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed &&
(sizeof(T) > 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// unsigned integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed &&
(sizeof(T) <= 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// JSValue -> unsigned integers <= 4 bytes
template <typename T>
inline void FromJSValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
ExceptionState* exception_state, T* out_number,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed &&
(sizeof(T) <= 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// JSValue -> unsigned integers > 4 bytes
template <typename T>
inline void FromJSValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
ExceptionState* exception_state, T* out_number,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed &&
(sizeof(T) > 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// unsigned integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed &&
(sizeof(T) > 4),
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// double -> JSValue
template <typename T>
inline void ToJSValue(
v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
!std::numeric_limits<T>::is_integer,
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// JSValue -> double
template <typename T>
inline void FromJSValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
ExceptionState* exception_state, T* out_number,
typename base::enable_if<std::numeric_limits<T>::is_specialized &&
!std::numeric_limits<T>::is_integer,
T>::type* = NULL) {
NOTIMPLEMENTED();
}
// optional<T> -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
const base::optional<T>& in_optional,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// JSValue -> optional<T>
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
base::optional<T>* out_optional) {
NOTIMPLEMENTED();
}
// JSValue -> optional<std::string>
template <>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
base::optional<std::string>* out_optional) {
NOTIMPLEMENTED();
}
// ValueHandle -> JSValue
void ToJSValue(v8::Isolate* isolate,
const ValueHandleHolder* value_handle_holder,
v8::Local<v8::Value>* out_value);
// JSValue -> ValueHandle
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
V8cValueHandleHolder* out_holder);
// object -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, const scoped_refptr<T>& in_object,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// raw object pointer -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, T* in_object,
v8::Local<v8::Value>* out_value) {
ToJSValue(isolate, scoped_refptr<T>(in_object), out_value);
}
// JSValue -> object
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
scoped_refptr<T>* out_object) {
DCHECK_EQ(conversion_flags & ~kConversionFlagsObject, 0)
<< "Unexpected conversion flags found.";
if (!value->IsObject()) {
NOTIMPLEMENTED();
return;
}
// TODO: Check if object implements interface and throw TypeError otherwise.
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
DCHECK(object->InternalFieldCount() == 1);
v8::Local<v8::External> external =
v8::Local<v8::External>::Cast(object->GetInternalField(0));
*out_object = scoped_refptr<T>(static_cast<T*>(
(static_cast<WrapperPrivate*>(external->Value()))->wrappable<T>().get()));
}
// CallbackInterface -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
const ScriptValue<T>* callback_interface,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
// JSValue -> CallbackInterface
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* out_exception,
V8cCallbackInterfaceHolder<T>* out_callback_interface) {
NOTIMPLEMENTED();
}
template <typename T>
void ToJSValue(v8::Isolate* isolate, const script::Sequence<T>& sequence,
v8::Local<v8::Value>* out_value) {
NOTIMPLEMENTED();
}
template <typename T>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
int conversion_flags, ExceptionState* exception_state,
script::Sequence<T>* out_sequence) {
NOTIMPLEMENTED();
}
} // namespace v8c
} // namespace script
} // namespace cobalt
// Union type conversion is generated by a pump script.
#include "cobalt/script/v8c/union_type_conversion_impl.h"
#endif // COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_