Skip to content

Commit

Permalink
Merge pull request #33 from sam-github/feature/v0.11-support
Browse files Browse the repository at this point in the history
Feature/v0.11 support
  • Loading branch information
jeremycx committed Sep 25, 2014
2 parents 4ec9b38 + bd73e50 commit 39eafd2
Show file tree
Hide file tree
Showing 7 changed files with 481 additions and 93 deletions.
251 changes: 251 additions & 0 deletions compat-inl.h
@@ -0,0 +1,251 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#ifndef COMPAT_INL_H_ // NOLINT(build/header_guard)
#define COMPAT_INL_H_ // NOLINT(build/header_guard)

#include "compat.h"

namespace compat {

#if COMPAT_NODE_VERSION == 10
#define COMPAT_ISOLATE
#define COMPAT_ISOLATE_
#else
#define COMPAT_ISOLATE isolate
#define COMPAT_ISOLATE_ isolate,
#endif

namespace I {

template <typename T>
inline void Use(const T&) {}

template <typename T>
inline v8::Local<T> ToLocal(v8::Local<T> handle) {
return handle;
}

#if COMPAT_NODE_VERSION == 10
template <typename T>
inline v8::Local<T> ToLocal(v8::Handle<T> handle) {
return v8::Local<T>::New(handle);
}
#endif

} // namespace I

v8::Local<v8::Boolean> True(v8::Isolate* isolate) {
I::Use(isolate);
return I::ToLocal<v8::Boolean>(v8::True(COMPAT_ISOLATE));
}

v8::Local<v8::Boolean> False(v8::Isolate* isolate) {
I::Use(isolate);
return I::ToLocal<v8::Boolean>(v8::False(COMPAT_ISOLATE));
}

v8::Local<v8::Primitive> Null(v8::Isolate* isolate) {
I::Use(isolate);
return I::ToLocal<v8::Primitive>(v8::Null(COMPAT_ISOLATE));
}

v8::Local<v8::Primitive> Undefined(v8::Isolate* isolate) {
I::Use(isolate);
return I::ToLocal<v8::Primitive>(v8::Undefined(COMPAT_ISOLATE));
}

v8::Local<v8::Array> Array::New(v8::Isolate* isolate, int length) {
I::Use(isolate);
return v8::Array::New(COMPAT_ISOLATE_ length);
}

v8::Local<v8::Boolean> Boolean::New(v8::Isolate* isolate, bool value) {
I::Use(isolate);
return I::ToLocal<v8::Boolean>(v8::Boolean::New(COMPAT_ISOLATE_ value));
}

v8::Local<v8::FunctionTemplate> FunctionTemplate::New(
v8::Isolate* isolate, FunctionCallback callback) {
I::Use(isolate);
return v8::FunctionTemplate::New(COMPAT_ISOLATE_ callback);
}

v8::Local<v8::Integer> Integer::New(v8::Isolate* isolate, int32_t value) {
I::Use(isolate);
return v8::Integer::New(COMPAT_ISOLATE_ value);
}

v8::Local<v8::Integer> Integer::NewFromUnsigned(v8::Isolate* isolate,
uint32_t value) {
I::Use(isolate);
return v8::Integer::NewFromUnsigned(COMPAT_ISOLATE_ value);
}

v8::Local<v8::Number> Number::New(v8::Isolate* isolate, double value) {
I::Use(isolate);
return v8::Number::New(COMPAT_ISOLATE_ value);
}

v8::Local<v8::Object> Object::New(v8::Isolate* isolate) {
I::Use(isolate);
return v8::Object::New(COMPAT_ISOLATE);
}

template <typename T>
Persistent<T>::~Persistent() {
// Trying to dispose the handle when the VM has been destroyed
// (e.g. at program exit) will segfault.
if (v8::V8::IsDead()) return;
Reset();
}

template <typename T>
bool Persistent<T>::IsEmpty() const {
return handle_.IsEmpty();
}

ReturnType ReturnableHandleScope::Return(bool value) {
return Return(Boolean::New(isolate(), value));
}

ReturnType ReturnableHandleScope::Return(intptr_t value) {
return Return(Integer::New(isolate(), value));
}

ReturnType ReturnableHandleScope::Return(int value) {
return Return(Integer::New(isolate(), value));
}

ReturnType ReturnableHandleScope::Return(double value) {
return Return(Number::New(isolate(), value));
}

ReturnType ReturnableHandleScope::Return(const char* value) {
return Return(String::NewFromUtf8(isolate(), value));
}

v8::Isolate* ReturnableHandleScope::isolate() const {
return args_.GetIsolate();
}

#if COMPAT_NODE_VERSION == 10

const v8::HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
v8::Isolate* isolate, v8::Local<v8::String> title) {
if (title.IsEmpty()) title = v8::String::Empty(isolate);
return v8::HeapProfiler::TakeSnapshot(title);
}

void HeapProfiler::DeleteAllHeapSnapshots(v8::Isolate* isolate) {
I::Use(isolate);
v8::HeapProfiler::DeleteAllSnapshots();
}

v8::Local<v8::String> String::NewFromUtf8(v8::Isolate* isolate,
const char* data, NewStringType type,
int length) {
I::Use(isolate);
if (type == kInternalizedString) {
return v8::String::NewSymbol(data, length);
}
if (type == kUndetectableString) {
return v8::String::NewUndetectable(data, length);
}
return v8::String::New(data, length);
}

HandleScope::HandleScope(v8::Isolate*) {}

template <typename T>
v8::Local<T> Persistent<T>::ToLocal(v8::Isolate*) const {
return *handle_;
}

template <typename T>
void Persistent<T>::Reset() {
handle_.Dispose();
handle_.Clear();
}

template <typename T>
void Persistent<T>::Reset(v8::Isolate*, v8::Local<T> value) {
Reset();
handle_ = v8::Persistent<T>::New(value);
}

ReturnableHandleScope::ReturnableHandleScope(const ArgumentType& args)
: args_(args) {}

ReturnType ReturnableHandleScope::Return() { return v8::Undefined(); }

ReturnType ReturnableHandleScope::Return(v8::Local<v8::Value> value) {
return handle_scope_.Close(value);
}

#elif COMPAT_NODE_VERSION == 12

const v8::HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
v8::Isolate* isolate, v8::Local<v8::String> title) {
if (title.IsEmpty()) title = v8::String::Empty(isolate);
return isolate->GetHeapProfiler()->TakeHeapSnapshot(title);
}

void HeapProfiler::DeleteAllHeapSnapshots(v8::Isolate* isolate) {
return isolate->GetHeapProfiler()->DeleteAllHeapSnapshots();
}

v8::Local<v8::String> String::NewFromUtf8(v8::Isolate* isolate,
const char* data, NewStringType type,
int length) {
return v8::String::NewFromUtf8(
isolate, data, static_cast<v8::String::NewStringType>(type), length);
}

HandleScope::HandleScope(v8::Isolate* isolate) : handle_scope_(isolate) {}

template <typename T>
v8::Local<T> Persistent<T>::ToLocal(v8::Isolate* isolate) const {
return v8::Local<T>::New(isolate, handle_);
}

template <typename T>
void Persistent<T>::Reset() {
handle_.Reset();
}

template <typename T>
void Persistent<T>::Reset(v8::Isolate* isolate, v8::Local<T> value) {
handle_.Reset(isolate, value);
}

ReturnableHandleScope::ReturnableHandleScope(const ArgumentType& args)
: args_(args), handle_scope_(args.GetIsolate()) {}

ReturnType ReturnableHandleScope::Return() {}

ReturnType ReturnableHandleScope::Return(v8::Local<v8::Value> value) {
// TODO(bnoordhuis) Creating handles for primitive values (int, double)
// is less efficient than passing them to ReturnValue<T>::Set() directly.
return args_.GetReturnValue().Set(value);
}

#endif

#undef COMPAT_ISOLATE_
#undef COMPAT_ISOLATE

} // namespace compat

#endif // COMPAT_INL_H_ // NOLINT(build/header_guard)
140 changes: 140 additions & 0 deletions compat.h
@@ -0,0 +1,140 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#ifndef COMPAT_H_ // NOLINT(build/header_guard)
#define COMPAT_H_ // NOLINT(build/header_guard)

#include "node_version.h"
#include "v8.h"
#include "v8-profiler.h"

#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION >= 11
#define COMPAT_NODE_VERSION 12 // v0.12
#elif NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION == 10
#define COMPAT_NODE_VERSION 10 // v0.10
#else
#error "Unsupported node.js version."
#endif

namespace compat {

#if COMPAT_NODE_VERSION == 10
typedef v8::Arguments ArgumentType;
typedef v8::Handle<v8::Value> ReturnType;
typedef v8::InvocationCallback FunctionCallback;
#elif COMPAT_NODE_VERSION == 12
typedef v8::FunctionCallbackInfo<v8::Value> ArgumentType;
typedef void ReturnType;
typedef v8::FunctionCallback FunctionCallback;
#endif

inline v8::Local<v8::Boolean> True(v8::Isolate* isolate);
inline v8::Local<v8::Boolean> False(v8::Isolate* isolate);
inline v8::Local<v8::Primitive> Null(v8::Isolate* isolate);
inline v8::Local<v8::Primitive> Undefined(v8::Isolate* isolate);

class AllStatic {
private:
AllStatic();
};

struct Array : public AllStatic {
inline static v8::Local<v8::Array> New(v8::Isolate* isolate, int length = 0);
};

struct Boolean : public AllStatic {
inline static v8::Local<v8::Boolean> New(v8::Isolate* isolate, bool value);
};

struct FunctionTemplate : public AllStatic {
inline static v8::Local<v8::FunctionTemplate> New(v8::Isolate* isolate,
FunctionCallback callback =
0);
};

struct HeapProfiler : public AllStatic {
inline static const v8::HeapSnapshot* TakeHeapSnapshot(
v8::Isolate* isolate,
v8::Local<v8::String> title = v8::Local<v8::String>());
inline static void DeleteAllHeapSnapshots(v8::Isolate* isolate);
};

struct Integer : public AllStatic {
inline static v8::Local<v8::Integer> New(v8::Isolate* isolate, int32_t value);
inline static v8::Local<v8::Integer> NewFromUnsigned(v8::Isolate* isolate,
uint32_t value);
};

struct Number : public AllStatic {
inline static v8::Local<v8::Number> New(v8::Isolate* isolate, double value);
};

struct Object : public AllStatic {
inline static v8::Local<v8::Object> New(v8::Isolate* isolate);
};

struct String : public AllStatic {
enum NewStringType {
kNormalString,
kInternalizedString,
kUndetectableString
};
inline static v8::Local<v8::String> NewFromUtf8(v8::Isolate* isolate,
const char* data,
NewStringType type =
kNormalString,
int length = -1);
};

class HandleScope {
public:
inline explicit HandleScope(v8::Isolate* isolate);

private:
v8::HandleScope handle_scope_;
};

template <typename T>
class Persistent {
public:
inline ~Persistent();
inline v8::Local<T> ToLocal(v8::Isolate* isolate) const;
inline void Reset();
inline void Reset(v8::Isolate* isolate, v8::Local<T> value);
inline bool IsEmpty() const;

private:
v8::Persistent<T> handle_;
};

class ReturnableHandleScope {
public:
inline explicit ReturnableHandleScope(const ArgumentType& args);
inline ReturnType Return();
inline ReturnType Return(bool value);
inline ReturnType Return(intptr_t value);
inline ReturnType Return(int value);
inline ReturnType Return(double value);
inline ReturnType Return(const char* value);
inline ReturnType Return(v8::Local<v8::Value> value);

private:
inline v8::Isolate* isolate() const;
const ArgumentType& args_;
v8::HandleScope handle_scope_;
};

} // namespace compat

#endif // COMPAT_H_ // NOLINT(build/header_guard)

0 comments on commit 39eafd2

Please sign in to comment.