//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany /// /// 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. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGODB_V8_V8__GLOBALS_H #define ARANGODB_V8_V8__GLOBALS_H 1 #include "Basics/Common.h" #include "ApplicationFeatures/V8PlatformFeature.h" #include "V8/JavaScriptSecurityContext.h" struct TRI_vocbase_t; namespace arangodb { class LogicalDataSource; // forward declaration } /// @brief shortcut for fetching the isolate from the thread context #define ISOLATE v8::Isolate* isolate = v8::Isolate::GetCurrent() /// @brief macro to initiate a try-catch sequence for V8 callbacks #define TRI_V8_TRY_CATCH_BEGIN(isolateVar) \ auto isolateVar = args.GetIsolate(); \ try { /// @brief macro to terminate a try-catch sequence for V8 callbacks #define TRI_V8_TRY_CATCH_END \ } \ catch (arangodb::basics::Exception const& ex) { \ TRI_V8_THROW_EXCEPTION_FULL(ex.code(), ex.what()); \ } \ catch (std::exception const& ex) { \ TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, ex.what()); \ } \ catch (...) { \ TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL); \ } static inline v8::Local v8OneByteStringFactory(v8::Isolate* isolate, void const* ptr, int length) { return v8::String::NewFromOneByte(isolate, static_cast(ptr), v8::NewStringType::kNormal, length) .ToLocalChecked(); } static inline v8::Local v8TwoByteStringFactory(v8::Isolate* isolate, void const* ptr, int length) { return v8::String::NewFromTwoByte(isolate, static_cast(ptr), v8::NewStringType::kNormal, length) .ToLocalChecked(); } static inline v8::Local v8Utf8StringFactory(v8::Isolate* isolate, void const* ptr, int length) { return v8::String::NewFromUtf8(isolate, static_cast(ptr), v8::NewStringType::kNormal, length) .ToLocalChecked(); } /// @brief shortcut for creating a v8 symbol for the specified string #define TRI_V8_ASCII_STRING(isolate, name) \ v8OneByteStringFactory(isolate, (name), (int)strlen(name)) #define TRI_V8_ASCII_STD_STRING(isolate, name) \ v8OneByteStringFactory(isolate, (name).data(), (int)(name).size()) #define TRI_V8_ASCII_PAIR_STRING(isolate, name, length) \ v8OneByteStringFactory(isolate, (name), (int)(length)) /// @brief shortcut for creating a v8 symbol for the specified string of unknown /// length #define TRI_V8_STRING(isolate, name) \ v8Utf8StringFactory(isolate, (name), (int)strlen(name)) /// @brief shortcut for creating a v8 symbol for the specified string #define TRI_V8_STD_STRING(isolate, name) \ v8Utf8StringFactory(isolate, (name).data(), (int)(name).size()) /// @brief shortcut for creating a v8 symbol for the specified string of known /// length #define TRI_V8_PAIR_STRING(isolate, name, length) \ v8Utf8StringFactory(isolate, (name), (int)(length)) /// @brief shortcut for creating a v8 symbol for the specified string #define TRI_V8_STRING_UTF16(isolate, name, length) \ v8TwoByteStringFactory(isolate, (name), (int)(length)) /// @brief shortcut for current v8 globals and scope #define TRI_V8_CURRENT_GLOBALS_AND_SCOPE \ TRI_v8_global_t* v8g = static_cast( \ isolate->GetData(arangodb::V8PlatformFeature::V8_DATA_SLOT)); \ v8::HandleScope scope(isolate); \ do { \ } while (0) #define TRI_CONTEXT \ auto context = isolate->GetCurrentContext(); /// @brief shortcut for throwing an exception with an error code #define TRI_V8_SET_EXCEPTION(code) \ do { \ TRI_CreateErrorObject(isolate, code); \ } while (0) #define TRI_V8_THROW_EXCEPTION(code) \ do { \ TRI_V8_SET_EXCEPTION(code); \ return; \ } while (0) /// @brief shortcut for throwing an exception and returning #define TRI_V8_SET_EXCEPTION_MESSAGE(code, message) \ do { \ TRI_CreateErrorObject(isolate, code, message, true); \ } while (0) #define TRI_V8_THROW_EXCEPTION_MESSAGE(code, message) \ do { \ TRI_V8_SET_EXCEPTION_MESSAGE(code, message); \ return; \ } while (0) /// @brief shortcut for throwing an exception and returning #define TRI_V8_THROW_EXCEPTION_FULL(code, message) \ do { \ TRI_CreateErrorObject(isolate, code, message, false); \ return; \ } while (0) /// @brief shortcut for throwing a usage exception and returning #define TRI_V8_THROW_EXCEPTION_USAGE(usage) \ do { \ std::string msg = "usage: "; \ msg += usage; \ TRI_CreateErrorObject(isolate, TRI_ERROR_BAD_PARAMETER, msg, false); \ return; \ } while (0) /// @brief shortcut for throwing an internal exception and returning #define TRI_V8_THROW_EXCEPTION_INTERNAL(message) \ do { \ TRI_CreateErrorObject(isolate, TRI_ERROR_INTERNAL, message, false); \ return; \ } while (0) /// @brief shortcut for throwing a parameter exception and returning #define TRI_V8_THROW_EXCEPTION_PARAMETER(message) \ do { \ TRI_CreateErrorObject(isolate, TRI_ERROR_BAD_PARAMETER, message, false); \ return; \ } while (0) /// @brief shortcut for throwing an out-of-memory exception and returning #define TRI_V8_SET_EXCEPTION_MEMORY() \ do { \ TRI_CreateErrorObject(isolate, TRI_ERROR_OUT_OF_MEMORY); \ } while (0) #define TRI_V8_THROW_EXCEPTION_MEMORY() \ do { \ TRI_V8_SET_EXCEPTION_MEMORY(); \ return; \ } while (0) /// @brief shortcut for throwing an exception for an system error #define TRI_V8_THROW_EXCEPTION_SYS(message) \ do { \ TRI_set_errno(TRI_ERROR_SYS_ERROR); \ std::string msg = message; \ msg += ": "; \ msg += TRI_LAST_ERROR_STR; \ TRI_CreateErrorObject(isolate, TRI_errno(), msg, false); \ return; \ } while (0) /// @brief shortcut for logging and forward throwing an error #define TRI_V8_LOG_THROW_EXCEPTION(TRYCATCH) \ do { \ TRI_LogV8Exception(isolate, &TRYCATCH); \ TRYCATCH.ReThrow(); \ return; \ } while (0) /// @brief shortcut for throwing an error #define TRI_V8_SET_ERROR(message) \ do { \ isolate->ThrowException(v8::Exception::Error(TRI_V8_STRING(isolate, message))); \ } while (0) #define TRI_V8_THROW_ERROR(message) \ do { \ TRI_V8_SET_ERROR(message); \ return; \ } while (0) /// @brief shortcut for throwing a range error #define TRI_V8_THROW_RANGE_ERROR(message) \ do { \ isolate->ThrowException(v8::Exception::RangeError(TRI_V8_STRING(isolate, message))); \ return; \ } while (0) /// @brief shortcut for throwing a syntax error #define TRI_V8_THROW_SYNTAX_ERROR(message) \ do { \ isolate->ThrowException(v8::Exception::SyntaxError(TRI_V8_STRING(isolate, message))); \ return; \ } while (0) /// @brief shortcut for throwing a type error #define TRI_V8_SET_TYPE_ERROR(message) \ do { \ isolate->ThrowException(v8::Exception::TypeError(TRI_V8_STRING(isolate, message))); \ } while (0) #define TRI_V8_THROW_TYPE_ERROR(message) \ do { \ TRI_V8_SET_TYPE_ERROR(message); \ return; \ } while (0) /// @brief "not yet implemented" handler for sharding #define TRI_THROW_SHARDING_COLLECTION_NOT_YET_IMPLEMENTED(collection) \ if (collection && ServerState::instance()->isCoordinator()) { \ TRI_V8_THROW_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED); \ } /// @brief Return undefined (default..) /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_UNDEFINED() \ args.GetReturnValue().Set(v8::Undefined(isolate)); \ return /// @brief Return 'true' /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_TRUE() \ args.GetReturnValue().Set(v8::True(isolate)); \ return /// @brief Return 'false' /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_FALSE() \ args.GetReturnValue().Set(v8::False(isolate)); \ return /// @brief Return a bool /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_BOOL(WHAT) \ if (WHAT) { \ args.GetReturnValue().Set(v8::True(isolate)); \ } else { \ args.GetReturnValue().Set(v8::False(isolate)); \ } \ return /// @brief Return an integer /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_INTEGER(WHAT) \ args.GetReturnValue().Set(v8::Integer::New(isolate, WHAT)); \ return /// @brief return 'null' /// implicitly requires 'args and 'isolate' to be available #define TRI_V8_RETURN_NULL() \ args.GetReturnValue().Set(v8::Null(isolate)); \ return /// @brief return any sort of V8-value /// implicitly requires 'args and 'isolate' to be available /// @param WHAT the name of the v8::Value/v8::Number/... #define TRI_V8_RETURN(WHAT) \ args.GetReturnValue().Set(WHAT); \ return /// @brief return a char* /// implicitly requires 'args and 'isolate' to be available /// @param WHAT the name of the char* variable #define TRI_V8_RETURN_STRING(WHAT) \ args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, WHAT, v8::NewStringType::kNormal) \ .FromMaybe(v8::Local())); \ return /// @brief return a std::string /// implicitly requires 'args and 'isolate' to be available /// @param WHAT the name of the std::string variable #define TRI_V8_RETURN_STD_STRING(WHAT) \ args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, WHAT.c_str(), \ v8::NewStringType::kNormal, \ (int)WHAT.length()) \ .FromMaybe(v8::Local())); \ return /// @brief return a std::wstring /// implicitly requires 'args and 'isolate' to be available /// @param WHAT the name of the std::string variable #define TRI_V8_RETURN_STD_WSTRING(WHAT) \ args.GetReturnValue().Set( \ v8::String::NewFromTwoByte(isolate, (const uint16_t*)WHAT.c_str(), \ v8::NewStringType::kNormal, (int)WHAT.length()) \ .FromMaybe(v8::Local())); \ return /// @brief return a string which you know the length of /// implicitly requires 'args and 'isolate' to be available /// @param WHAT the name of the char* variable /// @param WHATLEn the name of the int variable containing the length of WHAT #define TRI_V8_RETURN_PAIR_STRING(WHAT, WHATLEN) \ args.GetReturnValue().Set( \ v8::String::NewFromUtf8(isolate, WHAT, v8::NewStringType::kNormal, (int)WHATLEN)); \ return #define TRI_IGETC isolate->GetCurrentContext() #define TRI_GET_INT32(VAL) VAL->Int32Value(TRI_IGETC).FromMaybe(0) #define TRI_GET_UINT32(VAL) VAL->Uint32Value(TRI_IGETC).FromMaybe(0) #define TRI_GET_DOUBLE(VAL) VAL->NumberValue(TRI_IGETC).FromMaybe(0.0) #define TRI_GET_STRING(VAL) \ VAL->ToString(TRI_IGETC).FromMaybe(v8::Local()) inline v8::Local TRI_GetObject(v8::Local &context, v8::Handle const &val) { return val->ToObject(context).FromMaybe(v8::Local()); } inline bool TRI_HasProperty(v8::Local &context, v8::Isolate* isolate, v8::Local const& obj, char const *key) { return obj->Has(context, TRI_V8_ASCII_STRING(isolate, key)).FromMaybe(false); } inline bool TRI_HasProperty(v8::Local &context, v8::Isolate* isolate, v8::Local const& obj, v8::Local const& key) { return obj->Has(context, key).FromMaybe(false); } inline bool TRI_HasOwnProperty(v8::Local &context, v8::Isolate* isolate, v8::Local &obj, char const *key) { return obj->HasOwnProperty(context, TRI_V8_ASCII_STRING(isolate, key)).FromMaybe(false); } inline bool TRI_HasOwnProperty(v8::Local &context, v8::Isolate* isolate, v8::Local &obj, v8::Local &key) { return obj->HasOwnProperty(context, key).FromMaybe(false); } inline v8::Local TRI_GetProperty(v8::Local &context, v8::Isolate* isolate, v8::Local const& obj, char const *key) { return obj->Get(context, TRI_V8_ASCII_STRING(isolate, key)).FromMaybe(v8::Local()); } inline v8::Local TRI_GetProperty(v8::Local &context, v8::Isolate* isolate, v8::Local const& obj, v8::Local const& key) { return obj->Get(context, key).FromMaybe(v8::Local()); } inline bool TRI_DeleteProperty(v8::Local &context, v8::Isolate* isolate, v8::Local &obj, char const *key) { return obj->Delete(context, TRI_V8_ASCII_STRING(isolate, key)).FromMaybe(false); } inline bool TRI_DeleteProperty(v8::Local &context, v8::Isolate* isolate, v8::Local &obj, v8::Local const& key) { return obj->Delete(context, key).FromMaybe(false); } inline v8::Local TRI_ToObject(v8::Local &context, v8::Handle const& val) { return val->ToObject(context).FromMaybe(v8::Local()); } inline v8::Local TRI_ObjectToString(v8::Local &context, v8::Handle const &val) { return val->ToString(context).FromMaybe(v8::Local()); } /// @brief retrieve the instance of the TRI_v8_global of the current thread /// implicitly creates a variable 'v8g' with a pointer to it. /// implicitly requires 'isolate' to be available #define TRI_GET_GLOBALS() \ TRI_v8_global_t* v8g = static_cast( \ isolate->GetData(arangodb::V8PlatformFeature::V8_DATA_SLOT)) #define TRI_GET_GLOBALS2(isolate) \ TRI_v8_global_t* v8g = static_cast( \ isolate->GetData(arangodb::V8PlatformFeature::V8_DATA_SLOT)) /// @brief fetch a string-member from the global into the local scope of the /// function /// will give you a variable of the same name. /// implicitly requires 'v8g' and 'isolate' to be there. /// @param WHICH the member string name to get as local variable #define TRI_GET_GLOBAL_STRING(WHICH) \ auto WHICH = v8::Local::New(isolate, v8g->WHICH) /// @brief fetch a member from the global into the local scope of the function /// will give you a variable of the same name. /// implicitly requires 'v8g' and 'isolate' to be there. /// @param WHICH the member name to get as local variable /// @param TYPE the type of the member to instantiate #define TRI_GET_GLOBAL(WHICH, TYPE) \ auto WHICH = v8::Local::New(isolate, v8g->WHICH) /// @brief globals stored in the isolate struct TRI_v8_global_t { /// @brief wrapper around a v8::Persistent to hold a shared_ptr and cleanup class SharedPtrPersistent { public: SharedPtrPersistent( // constructor used ONLY by SharedPtrPersistent::emplace(...) v8::Isolate& isolate, // isolate std::shared_ptr const& value // value ); SharedPtrPersistent(SharedPtrPersistent&&) = delete; SharedPtrPersistent(SharedPtrPersistent const&) = delete; ~SharedPtrPersistent(); SharedPtrPersistent& operator=(SharedPtrPersistent&&) = delete; SharedPtrPersistent& operator=(SharedPtrPersistent const&) = delete; static std::pair emplace( // emplace persistent shared pointer v8::Isolate& isolate, // isolate std::shared_ptr const& value // value ); v8::Local get() const { return _persistent.Get(&_isolate); } private: v8::Isolate& _isolate; v8::Persistent _persistent; std::shared_ptr _value; }; explicit TRI_v8_global_t(v8::Isolate*, size_t id); ~TRI_v8_global_t(); /// @brief whether or not the context has active externals inline bool hasActiveExternals() const { return _activeExternals > 0; } /// @brief increase the number of active externals inline void increaseActiveExternals() { ++_activeExternals; } /// @brief decrease the number of active externals inline void decreaseActiveExternals() { --_activeExternals; } /// @brief agency template v8::Persistent AgencyTempl; /// @brief local agent template v8::Persistent AgentTempl; /// @brief clusterinfo template v8::Persistent ClusterInfoTempl; /// @brief server state template v8::Persistent ServerStateTempl; /// @brief cluster comm template v8::Persistent ClusterCommTempl; /// @brief ArangoError template v8::Persistent ArangoErrorTempl; /// @brief collection template v8::Persistent VocbaseColTempl; /// @brief view template v8::Persistent VocbaseViewTempl; /// @brief TRI_vocbase_t template v8::Persistent VocbaseTempl; /// @brief TRI_vocbase_t template v8::Persistent EnvTempl; /// @brief users template v8::Persistent UsersTempl; /// @brief general graphs module template v8::Persistent GeneralGraphModuleTempl; /// @brief general graph class template v8::Persistent GeneralGraphTempl; #ifdef USE_ENTERPRISE /// @brief smart graph class template v8::Persistent SmartGraphTempl; // there is no smart graph module becuase they are // identical, just return different graph instances. #endif /// @brief Buffer template v8::Persistent BufferTempl; /// @brief stream query cursor templace v8::Persistent StreamQueryCursorTempl; v8::Persistent IResearchAnalyzerTempl; // IResearch analyzer instance template v8::Persistent IResearchAnalyzersTempl; // IResearch analyzers feature template /// @brief "Buffer" constant v8::Persistent BufferConstant; /// @brief "DELETE" constant v8::Persistent DeleteConstant; /// @brief "GET" constant v8::Persistent GetConstant; /// @brief "HEAD" constant v8::Persistent HeadConstant; /// @brief "OPTIONS" constant v8::Persistent OptionsConstant; /// @brief "PATCH" constant v8::Persistent PatchConstant; /// @brief "POST" constant v8::Persistent PostConstant; /// @brief "PUT" constant v8::Persistent PutConstant; /// @brief "address" key name v8::Persistent AddressKey; /// @brief "allowUseDatabase" key name v8::Persistent AllowUseDatabaseKey; /// @brief "authorized" key name v8::Persistent AuthorizedKey; /// @brief "bodyFromFile" key name v8::Persistent BodyFromFileKey; /// @brief "body" key name v8::Persistent BodyKey; /// @brief "client" key name v8::Persistent ClientKey; /// @brief "code" key name v8::Persistent CodeKey; /// @brief "contentType" key name v8::Persistent ContentTypeKey; /// @brief "cookies" key name v8::Persistent CookiesKey; /// @brief "coordTransactionID" key name v8::Persistent CoordTransactionIDKey; /// @brief "database" key name v8::Persistent DatabaseKey; /// @brief "domain" key v8::Persistent DomainKey; /// @brief "endpoint" key name v8::Persistent EndpointKey; /// @brief "error" key name v8::Persistent ErrorKey; /// @brief "errorMessage" key name v8::Persistent ErrorMessageKey; /// @brief "errorNum" key name v8::Persistent ErrorNumKey; /// @brief "headers" key name v8::Persistent HeadersKey; /// @brief "httpOnly" key v8::Persistent HttpOnlyKey; /// @brief "id" key name v8::Persistent IdKey; /// @brief "isAdminUser" key name v8::Persistent IsAdminUser; /// @brief "initTimeout" key name v8::Persistent InitTimeoutKey; /// @brief "isRestore" key name v8::Persistent IsRestoreKey; /// @brief "isSynchronousReplication" key name v8::Persistent IsSynchronousReplicationKey; /// @brief "isSystem" key name v8::Persistent IsSystemKey; /// @brief "keepNull" key name v8::Persistent KeepNullKey; /// @brief "keyOptions" key name v8::Persistent KeyOptionsKey; /// @brief "length" key v8::Persistent LengthKey; /// @brief "lifeTime" key v8::Persistent LifeTimeKey; /// @brief "mergeObjects" key name v8::Persistent MergeObjectsKey; /// @brief "name" key v8::Persistent NameKey; /// @brief "operationID" key v8::Persistent OperationIDKey; /// @brief "overwrite" key v8::Persistent OverwriteKey; /// @brief "parameters" key name v8::Persistent ParametersKey; /// @brief "path" key name v8::Persistent PathKey; /// @brief "prefix" key name v8::Persistent PrefixKey; /// @brief "port" key name v8::Persistent PortKey; /// @brief "portType" key name v8::Persistent PortTypeKey; /// @brief "protocol" key name v8::Persistent ProtocolKey; /// @brief "rawSuffix" key name v8::Persistent RawSuffixKey; /// @brief "requestBody" key name v8::Persistent RequestBodyKey; /// @brief "requestType" key name v8::Persistent RequestTypeKey; /// @brief "responseCode" key name v8::Persistent ResponseCodeKey; /// @brief "returnNew" key name v8::Persistent ReturnNewKey; /// @brief "returnOld" key name v8::Persistent ReturnOldKey; /// @brief "secure" key v8::Persistent SecureKey; /// @brief "server" key v8::Persistent ServerKey; /// @brief "shardID" key name v8::Persistent ShardIDKey; /// @brief "silent" key name v8::Persistent SilentKey; /// @brief "singleRequest" key name v8::Persistent SingleRequestKey; /// @brief "status" key name v8::Persistent StatusKey; /// @brief "suffix" key name v8::Persistent SuffixKey; /// @brief "timeout" key name v8::Persistent TimeoutKey; /// @brief "toJson" key name v8::Persistent ToJsonKey; /// @brief "transformations" key name v8::Persistent TransformationsKey; /// @brief "url" key name v8::Persistent UrlKey; /// @brief "user" key name v8::Persistent UserKey; /// @brief "value" key v8::Persistent ValueKey; /// @brief "version" key v8::Persistent VersionKeyHidden; /// @brief "waitForSync" key name v8::Persistent WaitForSyncKey; /// @brief "_dbCache" key name v8::Persistent _DbCacheKey; /// @brief "_dbName" key name v8::Persistent _DbNameKey; /// @brief system attribute names v8::Persistent _IdKey; v8::Persistent _KeyKey; v8::Persistent _RevKey; v8::Persistent _FromKey; v8::Persistent _ToKey; /// @brief currently request object (might be invalid!) v8::Handle _currentRequest; /// @brief currently response object (might be invalid!) v8::Handle _currentResponse; /// @brief information about the currently running transaction void* _transactionContext; /// @brief pointer to the vocbase (TRI_vocbase_t*) TRI_vocbase_t* _vocbase; /// @brief number of v8 externals used in the context int64_t _activeExternals; /// @brief cancel has been caught bool _canceled; /// @brief the current security context arangodb::JavaScriptSecurityContext _securityContext; /// @brief true if the arango infrastructure is garbage collecting bool _inForcedCollect; /// @brief the ID that identifies this v8 context size_t const _id; std::atomic _lastMaxTime; std::atomic _countOfTimes; std::atomic _heapMax; std::atomic _heapLow; private: /// @brief shared pointer mapping for weak pointers, holds shared pointers so /// they don't get deallocated while in use by V8 /// @note used ONLY by the SharedPtrPersistent class std::unordered_map JSSharedPtrs; }; /// @brief creates a global context TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate*, size_t id); /// @brief gets the global context TRI_v8_global_t* TRI_GetV8Globals(v8::Isolate*); /// @brief adds a method to the prototype of an object template bool TRI_V8_AddProtoMethod(v8::Isolate* isolate, TARGET tpl, v8::Handle name, v8::FunctionCallback callback, bool isHidden = false) { // hidden method if (isHidden) { tpl->PrototypeTemplate()->Set(name, v8::FunctionTemplate::New(isolate, callback), v8::DontEnum); } // normal method else { tpl->PrototypeTemplate()->Set(name, v8::FunctionTemplate::New(isolate, callback)); } return true; } /// @brief adds a method to an object template inline bool TRI_V8_AddMethod(v8::Isolate* isolate, TARGET tpl, v8::Handle name, v8::Handle callback, bool isHidden = false) { // hidden method if (isHidden) { return tpl ->DefineOwnProperty(TRI_IGETC, name, callback->GetFunction(), v8::DontEnum) .FromMaybe(false); } // normal method else { return tpl->Set(name, callback->GetFunction()); } } template inline bool TRI_V8_AddMethod(v8::Isolate* isolate, TARGET tpl, v8::Handle name, v8::FunctionCallback callback, bool isHidden = false) { // hidden method if (isHidden) { return tpl ->DefineOwnProperty(TRI_IGETC, name, v8::FunctionTemplate::New(isolate, callback)->GetFunction(), v8::DontEnum) .FromMaybe(false); // Ignore ret } // normal method else { return tpl->Set(name, v8::FunctionTemplate::New(isolate, callback)->GetFunction()); } } template <> inline bool TRI_V8_AddMethod(v8::Isolate* isolate, v8::Handle tpl, v8::Handle name, v8::FunctionCallback callback, bool isHidden) { return TRI_V8_AddMethod(isolate, tpl->GetFunction(), name, callback, isHidden); } /// @brief adds a method to an object bool TRI_AddMethodVocbase(v8::Isolate* isolate, v8::Handle tpl, v8::Handle name, void (*func)(v8::FunctionCallbackInfo const&), bool isHidden = false); /// @brief adds a global function to the given context bool TRI_AddGlobalFunctionVocbase(v8::Isolate* isolate, v8::Handle name, void (*func)(v8::FunctionCallbackInfo const&), bool isHidden = false); /// @brief adds a global function to the given context bool TRI_AddGlobalFunctionVocbase(v8::Isolate* isolate, v8::Handle name, v8::Handle func, bool isHidden = false); /// @brief adds a global read-only variable to the given context bool TRI_AddGlobalVariableVocbase(v8::Isolate* isolate, v8::Handle name, v8::Handle value); #endif