Split up JS abstractions into type-specific files
This commit is contained in:
parent
d57483c675
commit
5c56a99403
|
@ -173,6 +173,22 @@
|
|||
F60102E31CBBB19700EC01BA /* node_object_accessor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = node_object_accessor.hpp; sourceTree = "<group>"; };
|
||||
F60102E71CBBB36500EC01BA /* jsc_object_accessor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = jsc_object_accessor.hpp; sourceTree = "<group>"; };
|
||||
F60102F71CBDA6D400EC01BA /* js_collection.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_collection.hpp; sourceTree = "<group>"; };
|
||||
F60103071CC4B3DF00EC01BA /* node_protected.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_protected.hpp; sourceTree = "<group>"; };
|
||||
F60103081CC4B4F900EC01BA /* jsc_protected.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_protected.hpp; sourceTree = "<group>"; };
|
||||
F60103091CC4B5E800EC01BA /* jsc_context.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_context.hpp; sourceTree = "<group>"; };
|
||||
F601030A1CC4B64E00EC01BA /* node_context.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_context.hpp; sourceTree = "<group>"; };
|
||||
F601030B1CC4B6C900EC01BA /* jsc_value.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_value.hpp; sourceTree = "<group>"; };
|
||||
F601030C1CC4B72B00EC01BA /* node_value.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_value.hpp; sourceTree = "<group>"; };
|
||||
F601030D1CC4B76F00EC01BA /* jsc_object.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_object.hpp; sourceTree = "<group>"; };
|
||||
F601030E1CC4B7C900EC01BA /* node_object.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_object.hpp; sourceTree = "<group>"; };
|
||||
F601030F1CC4B80800EC01BA /* jsc_function.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_function.hpp; sourceTree = "<group>"; };
|
||||
F60103101CC4B86000EC01BA /* node_function.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_function.hpp; sourceTree = "<group>"; };
|
||||
F60103111CC4BA6500EC01BA /* jsc_exception.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_exception.hpp; sourceTree = "<group>"; };
|
||||
F60103121CC4CBF000EC01BA /* node_exception.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_exception.hpp; sourceTree = "<group>"; };
|
||||
F60103131CC4CC4500EC01BA /* jsc_string.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_string.hpp; sourceTree = "<group>"; };
|
||||
F60103141CC4CC8C00EC01BA /* jsc_return_value.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_return_value.hpp; sourceTree = "<group>"; };
|
||||
F60103151CC4CCFD00EC01BA /* node_return_value.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_return_value.hpp; sourceTree = "<group>"; };
|
||||
F60103161CC4CD2F00EC01BA /* node_string.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_string.hpp; sourceTree = "<group>"; };
|
||||
F61378781C18EAAC008BFC51 /* js */ = {isa = PBXFileReference; lastKnownFileType = folder; path = js; sourceTree = "<group>"; };
|
||||
F620F0521CAF0B600082977B /* js_class.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_class.hpp; sourceTree = "<group>"; };
|
||||
F620F0531CAF2EF70082977B /* jsc_class.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsc_class.hpp; sourceTree = "<group>"; };
|
||||
|
@ -271,20 +287,17 @@
|
|||
children = (
|
||||
F6BCCFDF1C83809A00FE31AE /* lib */,
|
||||
F62A35131C18E6E2004A917D /* iOS */,
|
||||
F60103051CC4ADE500EC01BA /* JS */,
|
||||
F6874A441CAD2ACD00EEEE36 /* JSC */,
|
||||
F62BF9001CAC72C40022BCDC /* Node */,
|
||||
F62A35141C18E783004A917D /* Object Store */,
|
||||
F60102F71CBDA6D400EC01BA /* js_collection.hpp */,
|
||||
029048041C0428DF00ABDED4 /* js_list.hpp */,
|
||||
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */,
|
||||
029048061C0428DF00ABDED4 /* js_realm_object.hpp */,
|
||||
029048071C0428DF00ABDED4 /* js_realm.cpp */,
|
||||
029048081C0428DF00ABDED4 /* js_realm.hpp */,
|
||||
0290480A1C0428DF00ABDED4 /* js_results.hpp */,
|
||||
0290480C1C0428DF00ABDED4 /* js_schema.hpp */,
|
||||
F620F0521CAF0B600082977B /* js_class.hpp */,
|
||||
F6874A3E1CACA5A900EEEE36 /* js_types.hpp */,
|
||||
F6267BC91CADC30000AC36B1 /* js_util.hpp */,
|
||||
029048351C042A3C00ABDED4 /* platform.hpp */,
|
||||
0290480F1C0428DF00ABDED4 /* rpc.cpp */,
|
||||
029048101C0428DF00ABDED4 /* rpc.hpp */,
|
||||
|
@ -346,6 +359,17 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F60103051CC4ADE500EC01BA /* JS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F620F0521CAF0B600082977B /* js_class.hpp */,
|
||||
F6874A3E1CACA5A900EEEE36 /* js_types.hpp */,
|
||||
F6267BC91CADC30000AC36B1 /* js_util.hpp */,
|
||||
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */,
|
||||
);
|
||||
name = JS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F62A35131C18E6E2004A917D /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -408,6 +432,14 @@
|
|||
F620F0571CB766DA0082977B /* node_init.cpp */,
|
||||
F620F0551CB655A50082977B /* node_class.hpp */,
|
||||
F6874A351CAC792D00EEEE36 /* node_types.hpp */,
|
||||
F60103161CC4CD2F00EC01BA /* node_string.hpp */,
|
||||
F601030A1CC4B64E00EC01BA /* node_context.hpp */,
|
||||
F601030C1CC4B72B00EC01BA /* node_value.hpp */,
|
||||
F601030E1CC4B7C900EC01BA /* node_object.hpp */,
|
||||
F60103101CC4B86000EC01BA /* node_function.hpp */,
|
||||
F60103121CC4CBF000EC01BA /* node_exception.hpp */,
|
||||
F60103071CC4B3DF00EC01BA /* node_protected.hpp */,
|
||||
F60103151CC4CCFD00EC01BA /* node_return_value.hpp */,
|
||||
F60102E31CBBB19700EC01BA /* node_object_accessor.hpp */,
|
||||
);
|
||||
name = Node;
|
||||
|
@ -482,6 +514,14 @@
|
|||
029048011C0428DF00ABDED4 /* jsc_init.cpp */,
|
||||
F620F0531CAF2EF70082977B /* jsc_class.hpp */,
|
||||
025678951CAB392000FB8501 /* jsc_types.hpp */,
|
||||
F60103131CC4CC4500EC01BA /* jsc_string.hpp */,
|
||||
F60103091CC4B5E800EC01BA /* jsc_context.hpp */,
|
||||
F601030B1CC4B6C900EC01BA /* jsc_value.hpp */,
|
||||
F601030D1CC4B76F00EC01BA /* jsc_object.hpp */,
|
||||
F601030F1CC4B80800EC01BA /* jsc_function.hpp */,
|
||||
F60103111CC4BA6500EC01BA /* jsc_exception.hpp */,
|
||||
F60103081CC4B4F900EC01BA /* jsc_protected.hpp */,
|
||||
F60103141CC4CC8C00EC01BA /* jsc_return_value.hpp */,
|
||||
F60102E71CBBB36500EC01BA /* jsc_object_accessor.hpp */,
|
||||
);
|
||||
name = JSC;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
#include "js_class.hpp"
|
||||
#include "js_util.hpp"
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline JSGlobalContextRef jsc::Context::get_global_context(JSContextRef ctx) {
|
||||
return JSContextGetGlobalContext(ctx);
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,33 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Exception::value(JSContextRef ctx, const std::string &message) {
|
||||
JSValueRef value = jsc::Value::from_string(ctx, message);
|
||||
return JSObjectMakeError(ctx, 1, &value, NULL);
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,47 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Function::call(JSContextRef ctx, const JSObjectRef &function, const JSObjectRef &this_object, size_t argc, const JSValueRef arguments[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef result = JSObjectCallAsFunction(ctx, function, this_object, argc, arguments, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef &function, size_t argc, const JSValueRef arguments[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef result = JSObjectCallAsConstructor(ctx, function, argc, arguments, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -19,5 +19,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "jsc_init.h"
|
||||
#include "jsc_string.hpp"
|
||||
#include "jsc_protected.hpp"
|
||||
#include "jsc_context.hpp"
|
||||
#include "jsc_value.hpp"
|
||||
#include "jsc_object.hpp"
|
||||
#include "jsc_function.hpp"
|
||||
#include "jsc_exception.hpp"
|
||||
#include "jsc_return_value.hpp"
|
||||
#include "jsc_object_accessor.hpp"
|
||||
|
||||
#include "js_realm.hpp"
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
|
||||
return JSObjectHasProperty(ctx, object, key);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index) {
|
||||
return JSObjectHasProperty(ctx, object, jsc::String(util::to_string(index)));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef value = JSObjectGetProperty(ctx, object, key, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef value = JSObjectGetPropertyAtIndex(ctx, object, index, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key, const JSValueRef &value, PropertyAttributes attributes) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectSetProperty(ctx, object, key, value, attributes << 1, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectSetPropertyAtIndex(ctx, object, index, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::vector<jsc::String> jsc::Object::get_property_names(JSContextRef ctx, const JSObjectRef &object) {
|
||||
JSPropertyNameArrayRef property_names = JSObjectCopyPropertyNames(ctx, object);
|
||||
size_t property_count = JSPropertyNameArrayGetCount(property_names);
|
||||
|
||||
std::vector<jsc::String> names;
|
||||
names.reserve(property_count);
|
||||
|
||||
for (size_t i = 0; i < property_count; i++) {
|
||||
names.push_back(JSPropertyNameArrayGetNameAtIndex(property_names, i));
|
||||
}
|
||||
|
||||
JSPropertyNameArrayRelease(property_names);
|
||||
return names;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_prototype(JSContextRef ctx, const JSObjectRef &object) {
|
||||
return JSObjectGetPrototype(ctx, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_prototype(JSContextRef ctx, const JSObjectRef &object, const JSValueRef &prototype) {
|
||||
JSObjectSetPrototype(ctx, object, prototype);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_empty(JSContextRef ctx) {
|
||||
return JSObjectMake(ctx, nullptr, nullptr);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_array(JSContextRef ctx, uint32_t length, const JSValueRef values[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef array = JSObjectMakeArray(ctx, length, values, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_date(JSContextRef ctx, double time) {
|
||||
JSValueRef number = jsc::Value::from_number(ctx, time);
|
||||
return JSObjectMakeDate(ctx, 1, &number, nullptr);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline JSObjectRef jsc::Object::create_instance(JSContextRef ctx, typename ClassType::Internal* internal) {
|
||||
return jsc::ObjectWrap<ClassType>::create_instance(ctx, internal);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline bool jsc::Object::is_instance(JSContextRef ctx, const JSObjectRef &object) {
|
||||
return jsc::ObjectWrap<ClassType>::has_instance(ctx, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline typename ClassType::Internal* jsc::Object::get_internal(const JSObjectRef &object) {
|
||||
return *static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline void jsc::Object::set_internal(const JSObjectRef &object, typename ClassType::Internal* ptr) {
|
||||
auto wrap = static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
|
||||
*wrap = ptr;
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,78 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace jsc {
|
||||
|
||||
template<typename MemberType>
|
||||
class Protected {
|
||||
const MemberType m_value;
|
||||
|
||||
public:
|
||||
Protected(MemberType value) : m_value(value) {}
|
||||
|
||||
operator MemberType() const {
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
} // jsc
|
||||
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class Protected<JSGlobalContextRef> : public jsc::Protected<JSGlobalContextRef> {
|
||||
public:
|
||||
Protected(JSGlobalContextRef ctx) : jsc::Protected<JSGlobalContextRef>(ctx) {
|
||||
JSGlobalContextRetain(*this);
|
||||
}
|
||||
~Protected() {
|
||||
JSGlobalContextRelease(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<JSValueRef> : public jsc::Protected<JSValueRef> {
|
||||
const JSGlobalContextRef m_context;
|
||||
|
||||
public:
|
||||
Protected(JSContextRef ctx, JSValueRef value) : jsc::Protected<JSValueRef>(value), m_context(JSContextGetGlobalContext(ctx)) {
|
||||
JSValueProtect(m_context, *this);
|
||||
}
|
||||
~Protected() {
|
||||
JSValueUnprotect(m_context, *this);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<JSObjectRef> : public Protected<JSValueRef> {
|
||||
public:
|
||||
Protected(JSContextRef ctx, JSObjectRef object) : Protected<JSValueRef>(ctx, object) {}
|
||||
|
||||
operator JSObjectRef() const {
|
||||
JSValueRef value = static_cast<JSValueRef>(*this);
|
||||
return (JSObjectRef)value;
|
||||
}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,64 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class ReturnValue<jsc::Types> {
|
||||
const JSContextRef m_context;
|
||||
JSValueRef m_value = nullptr;
|
||||
|
||||
public:
|
||||
ReturnValue(JSContextRef ctx) : m_context(ctx) {}
|
||||
|
||||
void set(const JSValueRef &value) {
|
||||
m_value = value;
|
||||
}
|
||||
void set(const std::string &string) {
|
||||
m_value = JSValueMakeString(m_context, jsc::String(string));
|
||||
}
|
||||
void set(bool boolean) {
|
||||
m_value = JSValueMakeBoolean(m_context, boolean);
|
||||
}
|
||||
void set(double number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set(int32_t number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set(uint32_t number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set_null() {
|
||||
m_value = JSValueMakeNull(m_context);
|
||||
}
|
||||
void set_undefined() {
|
||||
m_value = JSValueMakeUndefined(m_context);
|
||||
}
|
||||
operator JSValueRef() const {
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,59 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class String<jsc::Types> {
|
||||
using StringType = String<jsc::Types>;
|
||||
|
||||
JSStringRef m_str;
|
||||
|
||||
public:
|
||||
String(const char *s) : m_str(JSStringCreateWithUTF8CString(s)) {}
|
||||
String(const JSStringRef &s) : m_str(JSStringRetain(s)) {}
|
||||
String(const std::string &str) : String(str.c_str()) {}
|
||||
String(const StringType &o) : String(o.m_str) {}
|
||||
String(StringType &&o) : m_str(o.m_str) {
|
||||
o.m_str = nullptr;
|
||||
}
|
||||
~String() {
|
||||
if (m_str) {
|
||||
JSStringRelease(m_str);
|
||||
}
|
||||
}
|
||||
|
||||
operator JSStringRef() const {
|
||||
return m_str;
|
||||
}
|
||||
operator std::string() const {
|
||||
size_t max_size = JSStringGetMaximumUTF8CStringSize(m_str);
|
||||
std::string string;
|
||||
string.resize(max_size);
|
||||
string.resize(JSStringGetUTF8CString(m_str, &string[0], max_size) - 1);
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -47,19 +47,7 @@ struct Types {
|
|||
using StringPropertyEnumeratorCallback = JSObjectGetPropertyNamesCallback;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Protected {
|
||||
const T m_value;
|
||||
|
||||
public:
|
||||
Protected(T value) : m_value(value) {}
|
||||
|
||||
operator T() const {
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename ClassType>
|
||||
class ObjectWrap;
|
||||
|
||||
using String = js::String<Types>;
|
||||
|
@ -71,430 +59,4 @@ using Exception = js::Exception<Types>;
|
|||
using ReturnValue = js::ReturnValue<Types>;
|
||||
|
||||
} // jsc
|
||||
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class String<jsc::Types> {
|
||||
using StringType = String<jsc::Types>;
|
||||
|
||||
JSStringRef m_str;
|
||||
|
||||
public:
|
||||
String(const char *s) : m_str(JSStringCreateWithUTF8CString(s)) {}
|
||||
String(const JSStringRef &s) : m_str(JSStringRetain(s)) {}
|
||||
String(const std::string &str) : String(str.c_str()) {}
|
||||
String(const StringType &o) : String(o.m_str) {}
|
||||
String(StringType &&o) : m_str(o.m_str) {
|
||||
o.m_str = nullptr;
|
||||
}
|
||||
~String() {
|
||||
if (m_str) {
|
||||
JSStringRelease(m_str);
|
||||
}
|
||||
}
|
||||
|
||||
operator JSStringRef() const {
|
||||
return m_str;
|
||||
}
|
||||
operator std::string() const {
|
||||
size_t max_size = JSStringGetMaximumUTF8CStringSize(m_str);
|
||||
std::string string;
|
||||
string.resize(max_size);
|
||||
string.resize(JSStringGetUTF8CString(m_str, &string[0], max_size) - 1);
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class ReturnValue<jsc::Types> {
|
||||
const JSContextRef m_context;
|
||||
JSValueRef m_value = nullptr;
|
||||
|
||||
public:
|
||||
ReturnValue(JSContextRef ctx) : m_context(ctx) {}
|
||||
|
||||
void set(const JSValueRef &value) {
|
||||
m_value = value;
|
||||
}
|
||||
void set(const std::string &string) {
|
||||
m_value = JSValueMakeString(m_context, jsc::String(string));
|
||||
}
|
||||
void set(bool boolean) {
|
||||
m_value = JSValueMakeBoolean(m_context, boolean);
|
||||
}
|
||||
void set(double number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set(int32_t number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set(uint32_t number) {
|
||||
m_value = JSValueMakeNumber(m_context, number);
|
||||
}
|
||||
void set_null() {
|
||||
m_value = JSValueMakeNull(m_context);
|
||||
}
|
||||
void set_undefined() {
|
||||
m_value = JSValueMakeUndefined(m_context);
|
||||
}
|
||||
operator JSValueRef() const {
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<JSGlobalContextRef> : public jsc::Protected<JSGlobalContextRef> {
|
||||
public:
|
||||
Protected(JSGlobalContextRef ctx) : jsc::Protected<JSGlobalContextRef>(ctx) {
|
||||
JSGlobalContextRetain(*this);
|
||||
}
|
||||
~Protected() {
|
||||
JSGlobalContextRelease(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<JSValueRef> : public jsc::Protected<JSValueRef> {
|
||||
const JSGlobalContextRef m_context;
|
||||
|
||||
public:
|
||||
Protected(JSContextRef ctx, JSValueRef value) : jsc::Protected<JSValueRef>(value), m_context(JSContextGetGlobalContext(ctx)) {
|
||||
JSValueProtect(m_context, *this);
|
||||
}
|
||||
~Protected() {
|
||||
JSValueUnprotect(m_context, *this);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<JSObjectRef> : public Protected<JSValueRef> {
|
||||
public:
|
||||
Protected(JSContextRef ctx, JSObjectRef object) : Protected<JSValueRef>(ctx, object) {}
|
||||
|
||||
operator JSObjectRef() const {
|
||||
JSValueRef value = static_cast<JSValueRef>(*this);
|
||||
return (JSObjectRef)value;
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool is_object_of_type(JSContextRef ctx, JSValueRef value, jsc::String type) {
|
||||
JSObjectRef global_object = JSContextGetGlobalObject(ctx);
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef constructor = JSObjectGetProperty(ctx, global_object, type, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
|
||||
bool result = JSValueIsInstanceOfConstructor(ctx, value, jsc::Value::validated_to_constructor(ctx, constructor), &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSGlobalContextRef jsc::Context::get_global_context(JSContextRef ctx) {
|
||||
return JSContextGetGlobalContext(ctx);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_array(JSContextRef ctx, const JSValueRef &value) {
|
||||
// JSValueIsArray() is not available until iOS 9.
|
||||
static const jsc::String type = "Array";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_array_buffer(JSContextRef ctx, const JSValueRef &value) {
|
||||
static const jsc::String type = "ArrayBuffer";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_date(JSContextRef ctx, const JSValueRef &value) {
|
||||
static const jsc::String type = "Date";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_boolean(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsBoolean(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_constructor(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value) && JSObjectIsConstructor(ctx, (JSObjectRef)value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_function(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value) && JSObjectIsFunction(ctx, (JSObjectRef)value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_null(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsNull(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_number(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsNumber(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_object(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_string(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsString(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_undefined(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsUndefined(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_valid(const JSValueRef &value) {
|
||||
return value != nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_boolean(JSContextRef ctx, bool boolean) {
|
||||
return JSValueMakeBoolean(ctx, boolean);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_null(JSContextRef ctx) {
|
||||
return JSValueMakeNull(ctx);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_number(JSContextRef ctx, double number) {
|
||||
return JSValueMakeNumber(ctx, number);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_string(JSContextRef ctx, const jsc::String &string) {
|
||||
return JSValueMakeString(ctx, string);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_undefined(JSContextRef ctx) {
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::to_boolean(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueToBoolean(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double jsc::Value::to_number(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
double number = JSValueToNumber(ctx, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
if (isnan(number)) {
|
||||
throw std::invalid_argument("Value not convertible to a number.");
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline jsc::String jsc::Value::to_string(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
jsc::String string = JSValueToStringCopy(ctx, value, &exception);
|
||||
|
||||
// Since the string's retain value is +2 here, we need to manually release it before returning.
|
||||
JSStringRelease(string);
|
||||
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_object(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef object = JSValueToObject(ctx, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_array(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_constructor(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_date(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_function(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Function::call(JSContextRef ctx, const JSObjectRef &function, const JSObjectRef &this_object, size_t argc, const JSValueRef arguments[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef result = JSObjectCallAsFunction(ctx, function, this_object, argc, arguments, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef &function, size_t argc, const JSValueRef arguments[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef result = JSObjectCallAsConstructor(ctx, function, argc, arguments, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
|
||||
return JSObjectHasProperty(ctx, object, key);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Object::has_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index) {
|
||||
return JSObjectHasProperty(ctx, object, jsc::String(util::to_string(index)));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef value = JSObjectGetProperty(ctx, object, key, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef value = JSObjectGetPropertyAtIndex(ctx, object, index, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_property(JSContextRef ctx, const JSObjectRef &object, const jsc::String &key, const JSValueRef &value, PropertyAttributes attributes) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectSetProperty(ctx, object, key, value, attributes << 1, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_property(JSContextRef ctx, const JSObjectRef &object, uint32_t index, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectSetPropertyAtIndex(ctx, object, index, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::vector<jsc::String> jsc::Object::get_property_names(JSContextRef ctx, const JSObjectRef &object) {
|
||||
JSPropertyNameArrayRef property_names = JSObjectCopyPropertyNames(ctx, object);
|
||||
size_t property_count = JSPropertyNameArrayGetCount(property_names);
|
||||
|
||||
std::vector<jsc::String> names;
|
||||
names.reserve(property_count);
|
||||
|
||||
for (size_t i = 0; i < property_count; i++) {
|
||||
names.push_back(JSPropertyNameArrayGetNameAtIndex(property_names, i));
|
||||
}
|
||||
|
||||
JSPropertyNameArrayRelease(property_names);
|
||||
return names;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Object::get_prototype(JSContextRef ctx, const JSObjectRef &object) {
|
||||
return JSObjectGetPrototype(ctx, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void jsc::Object::set_prototype(JSContextRef ctx, const JSObjectRef &object, const JSValueRef &prototype) {
|
||||
JSObjectSetPrototype(ctx, object, prototype);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_empty(JSContextRef ctx) {
|
||||
return JSObjectMake(ctx, nullptr, nullptr);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_array(JSContextRef ctx, uint32_t length, const JSValueRef values[]) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef array = JSObjectMakeArray(ctx, length, values, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Object::create_date(JSContextRef ctx, double time) {
|
||||
JSValueRef number = jsc::Value::from_number(ctx, time);
|
||||
return JSObjectMakeDate(ctx, 1, &number, nullptr);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline JSObjectRef jsc::Object::create_instance(JSContextRef ctx, typename ClassType::Internal* internal) {
|
||||
return jsc::ObjectWrap<ClassType>::create_instance(ctx, internal);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline bool jsc::Object::is_instance(JSContextRef ctx, const JSObjectRef &object) {
|
||||
return jsc::ObjectWrap<ClassType>::has_instance(ctx, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline typename ClassType::Internal* jsc::Object::get_internal(const JSObjectRef &object) {
|
||||
return *static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline void jsc::Object::set_internal(const JSObjectRef &object, typename ClassType::Internal* ptr) {
|
||||
auto wrap = static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
|
||||
*wrap = ptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Exception::value(JSContextRef ctx, const std::string &message) {
|
||||
JSValueRef value = jsc::Value::from_string(ctx, message);
|
||||
return JSObjectMakeError(ctx, 1, &value, NULL);
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsc_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
static inline bool is_object_of_type(JSContextRef ctx, JSValueRef value, jsc::String type) {
|
||||
JSObjectRef global_object = JSContextGetGlobalObject(ctx);
|
||||
JSValueRef exception = nullptr;
|
||||
JSValueRef constructor = JSObjectGetProperty(ctx, global_object, type, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
|
||||
bool result = JSValueIsInstanceOfConstructor(ctx, value, jsc::Value::validated_to_constructor(ctx, constructor), &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_array(JSContextRef ctx, const JSValueRef &value) {
|
||||
// JSValueIsArray() is not available until iOS 9.
|
||||
static const jsc::String type = "Array";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_array_buffer(JSContextRef ctx, const JSValueRef &value) {
|
||||
static const jsc::String type = "ArrayBuffer";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_date(JSContextRef ctx, const JSValueRef &value) {
|
||||
static const jsc::String type = "Date";
|
||||
return is_object_of_type(ctx, value, type);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_boolean(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsBoolean(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_constructor(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value) && JSObjectIsConstructor(ctx, (JSObjectRef)value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_function(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value) && JSObjectIsFunction(ctx, (JSObjectRef)value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_null(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsNull(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_number(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsNumber(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_object(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsObject(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_string(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsString(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_undefined(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueIsUndefined(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::is_valid(const JSValueRef &value) {
|
||||
return value != nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_boolean(JSContextRef ctx, bool boolean) {
|
||||
return JSValueMakeBoolean(ctx, boolean);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_null(JSContextRef ctx) {
|
||||
return JSValueMakeNull(ctx);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_number(JSContextRef ctx, double number) {
|
||||
return JSValueMakeNumber(ctx, number);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_string(JSContextRef ctx, const jsc::String &string) {
|
||||
return JSValueMakeString(ctx, string);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSValueRef jsc::Value::from_undefined(JSContextRef ctx) {
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool jsc::Value::to_boolean(JSContextRef ctx, const JSValueRef &value) {
|
||||
return JSValueToBoolean(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double jsc::Value::to_number(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
double number = JSValueToNumber(ctx, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
if (isnan(number)) {
|
||||
throw std::invalid_argument("Value not convertible to a number.");
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline jsc::String jsc::Value::to_string(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
jsc::String string = JSValueToStringCopy(ctx, value, &exception);
|
||||
|
||||
// Since the string's retain value is +2 here, we need to manually release it before returning.
|
||||
JSStringRelease(string);
|
||||
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_object(JSContextRef ctx, const JSValueRef &value) {
|
||||
JSValueRef exception = nullptr;
|
||||
JSObjectRef object = JSValueToObject(ctx, value, &exception);
|
||||
if (exception) {
|
||||
throw jsc::Exception(ctx, exception);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_array(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_constructor(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_date(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline JSObjectRef jsc::Value::to_function(JSContextRef ctx, const JSValueRef &value) {
|
||||
return to_object(ctx, value);
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
#include "js_class.hpp"
|
||||
#include "js_util.hpp"
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Context> node::Context::get_global_context(v8::Isolate* isolate) {
|
||||
return isolate->GetCurrentContext();
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,32 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Exception::value(v8::Isolate* isolate, const std::string &message) {
|
||||
return Nan::Error(message.c_str());
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,49 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Function::call(v8::Isolate* isolate, const v8::Local<v8::Function> &function, const v8::Local<v8::Object> &this_object, size_t argc, const v8::Local<v8::Value> arguments[]) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto result = Nan::Call(function, this_object, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return result.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Function::construct(v8::Isolate* isolate, const v8::Local<v8::Function> &function, size_t argc, const v8::Local<v8::Value> arguments[]) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto result = Nan::NewInstance(function, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return result.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -18,5 +18,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "node_string.hpp"
|
||||
#include "node_protected.hpp"
|
||||
#include "node_context.hpp"
|
||||
#include "node_value.hpp"
|
||||
#include "node_object.hpp"
|
||||
#include "node_function.hpp"
|
||||
#include "node_exception.hpp"
|
||||
#include "node_return_value.hpp"
|
||||
#include "node_object_accessor.hpp"
|
||||
|
||||
#include "js_realm.hpp"
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
|
||||
return Nan::Has(object, key).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index) {
|
||||
return Nan::Has(object, index).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto value = Nan::Get(object, v8::Local<v8::String>(key));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return value.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto value = Nan::Get(object, index);
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return value.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key, const v8::Local<v8::Value> &value, PropertyAttributes attributes) {
|
||||
Nan::TryCatch trycatch;
|
||||
|
||||
if (attributes) {
|
||||
Nan::ForceSet(object, v8::Local<v8::String>(key), value, v8::PropertyAttribute(attributes));
|
||||
}
|
||||
else {
|
||||
Nan::Set(object, v8::Local<v8::String>(key), value);
|
||||
}
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index, const v8::Local<v8::Value> &value) {
|
||||
Nan::TryCatch trycatch;
|
||||
Nan::Set(object, index, value);
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::vector<node::String> node::Object::get_property_names(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
auto maybe_array = Nan::GetPropertyNames(object);
|
||||
if (maybe_array.IsEmpty()) {
|
||||
return std::vector<node::String>();
|
||||
}
|
||||
|
||||
auto array = maybe_array.ToLocalChecked();
|
||||
uint32_t count = array->Length();
|
||||
|
||||
std::vector<node::String> names;
|
||||
names.reserve(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
names.push_back(array->Get(i)->ToString());
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_prototype(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
return object->GetPrototype();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_prototype(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const v8::Local<v8::Value> &prototype) {
|
||||
Nan::SetPrototype(object, prototype);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_empty(v8::Isolate* isolate) {
|
||||
return Nan::New<v8::Object>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_array(v8::Isolate* isolate, uint32_t length, const v8::Local<v8::Value> values[]) {
|
||||
v8::Local<v8::Array> array = Nan::New<v8::Array>(length);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
set_property(isolate, array, i, values[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_date(v8::Isolate* isolate, double time) {
|
||||
return Nan::New<v8::Date>(time).ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline v8::Local<v8::Object> node::Object::create_instance(v8::Isolate* isolate, typename ClassType::Internal* internal) {
|
||||
return node::ObjectWrap<ClassType>::create_instance(isolate, internal);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline bool node::Object::is_instance(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
return node::ObjectWrap<ClassType>::has_instance(isolate, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline typename ClassType::Internal* node::Object::get_internal(const v8::Local<v8::Object> &object) {
|
||||
return *Nan::ObjectWrap::Unwrap<node::ObjectWrap<ClassType>>(object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline void node::Object::set_internal(const v8::Local<v8::Object> &object, typename ClassType::Internal* ptr) {
|
||||
auto wrap = Nan::ObjectWrap::Unwrap<node::ObjectWrap<ClassType>>(object);
|
||||
*wrap = ptr;
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,84 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace node {
|
||||
|
||||
template<typename MemberType>
|
||||
class Protected {
|
||||
// TODO: Figure out why Nan::CopyablePersistentTraits causes a build failure.
|
||||
Nan::Persistent<MemberType, v8::CopyablePersistentTraits<MemberType>> m_value;
|
||||
|
||||
public:
|
||||
Protected(v8::Local<MemberType> value) : m_value(value) {}
|
||||
|
||||
operator v8::Local<MemberType>() const {
|
||||
return Nan::New(m_value);
|
||||
}
|
||||
bool operator==(const v8::Local<MemberType> &other) const {
|
||||
return m_value == other;
|
||||
}
|
||||
bool operator!=(const v8::Local<MemberType> &other) const {
|
||||
return m_value != other;
|
||||
}
|
||||
bool operator==(const Protected<MemberType> &other) const {
|
||||
return m_value == other.m_value;
|
||||
}
|
||||
bool operator!=(const Protected<MemberType> &other) const {
|
||||
return m_value != other.m_value;
|
||||
}
|
||||
};
|
||||
|
||||
} // node
|
||||
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::GlobalContext> : public node::Protected<v8::Context> {
|
||||
public:
|
||||
Protected(v8::Local<v8::Context> ctx) : node::Protected<v8::Context>(ctx) {}
|
||||
|
||||
operator v8::Isolate*() const {
|
||||
return v8::Local<v8::Context>(*this)->GetIsolate();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Value> : public node::Protected<v8::Value> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Value> value) : node::Protected<v8::Value>(value) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Object> : public node::Protected<v8::Object> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Object> object) : node::Protected<v8::Object>(object) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Function> : public node::Protected<v8::Function> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Function> object) : node::Protected<v8::Function>(object) {}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,65 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class ReturnValue<node::Types> {
|
||||
Nan::ReturnValue<v8::Value> m_value;
|
||||
|
||||
public:
|
||||
ReturnValue(Nan::ReturnValue<v8::Value> value) : m_value(value) {}
|
||||
|
||||
void set(const v8::Local<v8::Value> &value) {
|
||||
m_value.Set(value);
|
||||
}
|
||||
void set(const std::string &string) {
|
||||
if (string.empty()) {
|
||||
m_value.SetEmptyString();
|
||||
}
|
||||
else {
|
||||
m_value.Set(Nan::New(string).ToLocalChecked());
|
||||
}
|
||||
}
|
||||
void set(bool boolean) {
|
||||
m_value.Set(boolean);
|
||||
}
|
||||
void set(double number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set(int32_t number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set(uint32_t number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set_null() {
|
||||
m_value.SetNull();
|
||||
}
|
||||
void set_undefined() {
|
||||
m_value.SetUndefined();
|
||||
}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -0,0 +1,45 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class String<node::Types> {
|
||||
std::string m_str;
|
||||
|
||||
public:
|
||||
String(const char* s) : m_str(s) {}
|
||||
String(const std::string &s) : m_str(s) {}
|
||||
String(const v8::Local<v8::String> &s) : m_str(*Nan::Utf8String(s)) {}
|
||||
String(v8::Local<v8::String> &&s) : String(s) {}
|
||||
|
||||
operator std::string() const {
|
||||
return m_str;
|
||||
}
|
||||
operator v8::Local<v8::String>() const {
|
||||
return Nan::New(m_str).ToLocalChecked();
|
||||
}
|
||||
};
|
||||
|
||||
} // js
|
||||
} // realm
|
|
@ -53,32 +53,7 @@ struct Types {
|
|||
using StringPropertyEnumeratorCallback = Nan::PropertyEnumeratorCallback;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Protected {
|
||||
// TODO: Figure out why Nan::CopyablePersistentTraits causes a build failure.
|
||||
Nan::Persistent<T, v8::CopyablePersistentTraits<T>> m_value;
|
||||
|
||||
public:
|
||||
Protected(v8::Local<T> value) : m_value(value) {}
|
||||
|
||||
operator v8::Local<T>() const {
|
||||
return Nan::New(m_value);
|
||||
}
|
||||
bool operator==(const v8::Local<T> &other) const {
|
||||
return m_value == other;
|
||||
}
|
||||
bool operator!=(const v8::Local<T> &other) const {
|
||||
return m_value != other;
|
||||
}
|
||||
bool operator==(const Protected<T> &other) const {
|
||||
return m_value == other.m_value;
|
||||
}
|
||||
bool operator!=(const Protected<T> &other) const {
|
||||
return m_value != other.m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename ClassType>
|
||||
class ObjectWrap;
|
||||
|
||||
using String = js::String<Types>;
|
||||
|
@ -90,398 +65,4 @@ using Exception = js::Exception<Types>;
|
|||
using ReturnValue = js::ReturnValue<Types>;
|
||||
|
||||
} // node
|
||||
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
class String<node::Types> {
|
||||
std::string m_str;
|
||||
|
||||
public:
|
||||
String(const char* s) : m_str(s) {}
|
||||
String(const std::string &s) : m_str(s) {}
|
||||
String(const v8::Local<v8::String> &s) : m_str(*Nan::Utf8String(s)) {}
|
||||
String(v8::Local<v8::String> &&s) : String(s) {}
|
||||
|
||||
operator std::string() const {
|
||||
return m_str;
|
||||
}
|
||||
operator v8::Local<v8::String>() const {
|
||||
return Nan::New(m_str).ToLocalChecked();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class ReturnValue<node::Types> {
|
||||
Nan::ReturnValue<v8::Value> m_value;
|
||||
|
||||
public:
|
||||
ReturnValue(Nan::ReturnValue<v8::Value> value) : m_value(value) {}
|
||||
|
||||
void set(const v8::Local<v8::Value> &value) {
|
||||
m_value.Set(value);
|
||||
}
|
||||
void set(const std::string &string) {
|
||||
if (string.empty()) {
|
||||
m_value.SetEmptyString();
|
||||
}
|
||||
else {
|
||||
m_value.Set(Nan::New(string).ToLocalChecked());
|
||||
}
|
||||
}
|
||||
void set(bool boolean) {
|
||||
m_value.Set(boolean);
|
||||
}
|
||||
void set(double number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set(int32_t number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set(uint32_t number) {
|
||||
m_value.Set(number);
|
||||
}
|
||||
void set_null() {
|
||||
m_value.SetNull();
|
||||
}
|
||||
void set_undefined() {
|
||||
m_value.SetUndefined();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::GlobalContext> : public node::Protected<v8::Context> {
|
||||
public:
|
||||
Protected(v8::Local<v8::Context> ctx) : node::Protected<v8::Context>(ctx) {}
|
||||
|
||||
operator v8::Isolate*() const {
|
||||
return v8::Local<v8::Context>(*this)->GetIsolate();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Value> : public node::Protected<v8::Value> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Value> value) : node::Protected<v8::Value>(value) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Object> : public node::Protected<v8::Object> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Object> object) : node::Protected<v8::Object>(object) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Protected<node::Types::Function> : public node::Protected<v8::Function> {
|
||||
public:
|
||||
Protected(v8::Isolate* isolate, v8::Local<v8::Function> object) : node::Protected<v8::Function>(object) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Context> node::Context::get_global_context(v8::Isolate* isolate) {
|
||||
return isolate->GetCurrentContext();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsArray();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array_buffer(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
#if REALM_V8_ARRAY_BUFFER_API
|
||||
return value->IsArrayBuffer();
|
||||
#else
|
||||
// TODO: Implement this!
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array_buffer_view(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
#if REALM_V8_ARRAY_BUFFER_API
|
||||
return value->IsArrayBufferView();
|
||||
#else
|
||||
// TODO: Implement this!
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_date(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsDate();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_boolean(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsBoolean();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_constructor(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_function(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_null(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsNull();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_number(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsNumber();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_object(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsObject();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_string(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsString();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_undefined(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsUndefined();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_valid(const v8::Local<v8::Value> &value) {
|
||||
return !value.IsEmpty();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_boolean(v8::Isolate* isolate, bool boolean) {
|
||||
return Nan::New(boolean);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_null(v8::Isolate* isolate) {
|
||||
return Nan::Null();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_number(v8::Isolate* isolate, double number) {
|
||||
return Nan::New(number);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_string(v8::Isolate* isolate, const node::String &string) {
|
||||
return v8::Local<v8::String>(string);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_undefined(v8::Isolate* isolate) {
|
||||
return Nan::Undefined();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::to_boolean(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return Nan::To<bool>(value).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double node::Value::to_number(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
double number = Nan::To<double>(value).FromMaybe(NAN);
|
||||
if (isnan(number)) {
|
||||
throw std::invalid_argument("Value not convertible to a number.");
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline node::String node::Value::to_string(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->ToString();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_object(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return Nan::To<v8::Object>(value).FromMaybe(v8::Local<v8::Object>());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_array(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_object(isolate, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_date(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_object(isolate, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Function> node::Value::to_function(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction() ? v8::Local<v8::Function>::Cast(value) : v8::Local<v8::Function>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Function> node::Value::to_constructor(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_function(isolate, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Function::call(v8::Isolate* isolate, const v8::Local<v8::Function> &function, const v8::Local<v8::Object> &this_object, size_t argc, const v8::Local<v8::Value> arguments[]) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto result = Nan::Call(function, this_object, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return result.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Function::construct(v8::Isolate* isolate, const v8::Local<v8::Function> &function, size_t argc, const v8::Local<v8::Value> arguments[]) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto result = Nan::NewInstance(function, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return result.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
|
||||
return Nan::Has(object, key).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Object::has_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index) {
|
||||
return Nan::Has(object, index).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto value = Nan::Get(object, v8::Local<v8::String>(key));
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return value.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index) {
|
||||
Nan::TryCatch trycatch;
|
||||
auto value = Nan::Get(object, index);
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
return value.ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const node::String &key, const v8::Local<v8::Value> &value, PropertyAttributes attributes) {
|
||||
Nan::TryCatch trycatch;
|
||||
|
||||
if (attributes) {
|
||||
Nan::ForceSet(object, v8::Local<v8::String>(key), value, v8::PropertyAttribute(attributes));
|
||||
}
|
||||
else {
|
||||
Nan::Set(object, v8::Local<v8::String>(key), value);
|
||||
}
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_property(v8::Isolate* isolate, const v8::Local<v8::Object> &object, uint32_t index, const v8::Local<v8::Value> &value) {
|
||||
Nan::TryCatch trycatch;
|
||||
Nan::Set(object, index, value);
|
||||
|
||||
if (trycatch.HasCaught()) {
|
||||
throw node::Exception(isolate, trycatch.Exception());
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::vector<node::String> node::Object::get_property_names(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
auto maybe_array = Nan::GetPropertyNames(object);
|
||||
if (maybe_array.IsEmpty()) {
|
||||
return std::vector<node::String>();
|
||||
}
|
||||
|
||||
auto array = maybe_array.ToLocalChecked();
|
||||
uint32_t count = array->Length();
|
||||
|
||||
std::vector<node::String> names;
|
||||
names.reserve(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
names.push_back(array->Get(i)->ToString());
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Object::get_prototype(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
return object->GetPrototype();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void node::Object::set_prototype(v8::Isolate* isolate, const v8::Local<v8::Object> &object, const v8::Local<v8::Value> &prototype) {
|
||||
Nan::SetPrototype(object, prototype);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_empty(v8::Isolate* isolate) {
|
||||
return Nan::New<v8::Object>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_array(v8::Isolate* isolate, uint32_t length, const v8::Local<v8::Value> values[]) {
|
||||
v8::Local<v8::Array> array = Nan::New<v8::Array>(length);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
set_property(isolate, array, i, values[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Object::create_date(v8::Isolate* isolate, double time) {
|
||||
return Nan::New<v8::Date>(time).ToLocalChecked();
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline v8::Local<v8::Object> node::Object::create_instance(v8::Isolate* isolate, typename ClassType::Internal* internal) {
|
||||
return node::ObjectWrap<ClassType>::create_instance(isolate, internal);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline bool node::Object::is_instance(v8::Isolate* isolate, const v8::Local<v8::Object> &object) {
|
||||
return node::ObjectWrap<ClassType>::has_instance(isolate, object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline typename ClassType::Internal* node::Object::get_internal(const v8::Local<v8::Object> &object) {
|
||||
return *Nan::ObjectWrap::Unwrap<node::ObjectWrap<ClassType>>(object);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename ClassType>
|
||||
inline void node::Object::set_internal(const v8::Local<v8::Object> &object, typename ClassType::Internal* ptr) {
|
||||
auto wrap = Nan::ObjectWrap::Unwrap<node::ObjectWrap<ClassType>>(object);
|
||||
*wrap = ptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Exception::value(v8::Isolate* isolate, const std::string &message) {
|
||||
return Nan::Error(message.c_str());
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_types.hpp"
|
||||
|
||||
namespace realm {
|
||||
namespace js {
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsArray();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array_buffer(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
#if REALM_V8_ARRAY_BUFFER_API
|
||||
return value->IsArrayBuffer();
|
||||
#else
|
||||
// TODO: Implement this!
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_array_buffer_view(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
#if REALM_V8_ARRAY_BUFFER_API
|
||||
return value->IsArrayBufferView();
|
||||
#else
|
||||
// TODO: Implement this!
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_date(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsDate();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_boolean(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsBoolean();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_constructor(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_function(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_null(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsNull();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_number(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsNumber();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_object(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsObject();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_string(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsString();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_undefined(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsUndefined();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::is_valid(const v8::Local<v8::Value> &value) {
|
||||
return !value.IsEmpty();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_boolean(v8::Isolate* isolate, bool boolean) {
|
||||
return Nan::New(boolean);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_null(v8::Isolate* isolate) {
|
||||
return Nan::Null();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_number(v8::Isolate* isolate, double number) {
|
||||
return Nan::New(number);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_string(v8::Isolate* isolate, const node::String &string) {
|
||||
return v8::Local<v8::String>(string);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Value> node::Value::from_undefined(v8::Isolate* isolate) {
|
||||
return Nan::Undefined();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool node::Value::to_boolean(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return Nan::To<bool>(value).FromMaybe(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double node::Value::to_number(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
double number = Nan::To<double>(value).FromMaybe(NAN);
|
||||
if (isnan(number)) {
|
||||
throw std::invalid_argument("Value not convertible to a number.");
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline node::String node::Value::to_string(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->ToString();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_object(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return Nan::To<v8::Object>(value).FromMaybe(v8::Local<v8::Object>());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_array(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_object(isolate, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Object> node::Value::to_date(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_object(isolate, value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Function> node::Value::to_function(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return value->IsFunction() ? v8::Local<v8::Function>::Cast(value) : v8::Local<v8::Function>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline v8::Local<v8::Function> node::Value::to_constructor(v8::Isolate* isolate, const v8::Local<v8::Value> &value) {
|
||||
return to_function(isolate, value);
|
||||
}
|
||||
|
||||
} // js
|
||||
} // realm
|
Loading…
Reference in New Issue