Initial commit.
This commit is contained in:
commit
ff65b7dae1
20 changed files with 1887 additions and 0 deletions
20
LICENSE
Normal file
20
LICENSE
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (c) 2014 Cheng Zhao.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
LICENSE.chromium
Normal file
27
LICENSE.chromium
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
48
native_mate/arguments.cc
Normal file
48
native_mate/arguments.cc
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/arguments.h"
|
||||||
|
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
Arguments::Arguments()
|
||||||
|
: isolate_(NULL),
|
||||||
|
info_(NULL),
|
||||||
|
next_(0),
|
||||||
|
insufficient_arguments_(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Arguments::Arguments(const MATE_METHOD_ARGS_TYPE& info)
|
||||||
|
: isolate_(info.GetIsolate()),
|
||||||
|
info_(&info),
|
||||||
|
next_(0),
|
||||||
|
insufficient_arguments_(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Arguments::~Arguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::Value> Arguments::PeekNext() const {
|
||||||
|
if (next_ >= info_->Length())
|
||||||
|
return v8::Handle<v8::Value>();
|
||||||
|
return (*info_)[next_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Arguments::ThrowError() const {
|
||||||
|
if (insufficient_arguments_)
|
||||||
|
return ThrowTypeError("Insufficient number of arguments.");
|
||||||
|
|
||||||
|
ThrowTypeError(base::StringPrintf(
|
||||||
|
"Error processing argument %d.", next_ - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Arguments::ThrowTypeError(const std::string& message) const {
|
||||||
|
MATE_THROW_EXCEPTION(isolate_, v8::Exception::TypeError(
|
||||||
|
StringToV8(isolate_, message)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
82
native_mate/arguments.h
Normal file
82
native_mate/arguments.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_ARGUMENTS_H_
|
||||||
|
#define NATIVE_MATE_ARGUMENTS_H_
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "native_mate/compat.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
// Arguments is a wrapper around v8::FunctionCallbackInfo that integrates
|
||||||
|
// with Converter to make it easier to marshall arguments and return values
|
||||||
|
// between V8 and C++.
|
||||||
|
class Arguments {
|
||||||
|
public:
|
||||||
|
Arguments();
|
||||||
|
explicit Arguments(const MATE_METHOD_ARGS_TYPE& info);
|
||||||
|
~Arguments();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool GetHolder(T* out) {
|
||||||
|
return ConvertFromV8(isolate_, info_->Holder(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool GetData(T* out) {
|
||||||
|
return ConvertFromV8(isolate_, info_->Data(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool GetNext(T* out) {
|
||||||
|
if (next_ >= info_->Length()) {
|
||||||
|
insufficient_arguments_ = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
v8::Handle<v8::Value> val = (*info_)[next_++];
|
||||||
|
return ConvertFromV8(isolate_, val, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool GetRemaining(std::vector<T>* out) {
|
||||||
|
if (next_ >= info_->Length()) {
|
||||||
|
insufficient_arguments_ = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int remaining = info_->Length() - next_;
|
||||||
|
out->resize(remaining);
|
||||||
|
for (int i = 0; i < remaining; ++i) {
|
||||||
|
v8::Handle<v8::Value> val = (*info_)[next_++];
|
||||||
|
if (!ConvertFromV8(isolate_, val, &out->at(i)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NODE_VERSION_AT_LEAST(0, 11, 0)
|
||||||
|
template<typename T>
|
||||||
|
void Return(T val) {
|
||||||
|
info_->GetReturnValue().Set(ConvertToV8(isolate_, val));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v8::Handle<v8::Value> PeekNext() const;
|
||||||
|
|
||||||
|
void ThrowError() const;
|
||||||
|
void ThrowTypeError(const std::string& message) const;
|
||||||
|
|
||||||
|
v8::Isolate* isolate() const { return isolate_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
v8::Isolate* isolate_;
|
||||||
|
const MATE_METHOD_ARGS_TYPE* info_;
|
||||||
|
int next_;
|
||||||
|
bool insufficient_arguments_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_ARGUMENTS_H_
|
100
native_mate/compat.h
Normal file
100
native_mate/compat.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright 2014 Cheng Zhao. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license that can be found in the
|
||||||
|
// LICENSE file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_COMPAT_H_
|
||||||
|
#define NATIVE_MATE_COMPAT_H_
|
||||||
|
|
||||||
|
#include "node_version.h"
|
||||||
|
|
||||||
|
#if (NODE_MODULE_VERSION > 0x000B) // Node 0.11+
|
||||||
|
|
||||||
|
#define MATE_HANDLE_SCOPE(isolate) v8::HandleScope handle_scope(isolate)
|
||||||
|
|
||||||
|
#define MATE_METHOD_ARGS_TYPE v8::FunctionCallbackInfo<v8::Value>
|
||||||
|
#define MATE_METHOD_RETURN_TYPE void
|
||||||
|
|
||||||
|
#define MATE_METHOD_RETURN_VALUE(value) return info.GetReturnValue().Set(value)
|
||||||
|
#define MATE_METHOD_RETURN_UNDEFINED() return
|
||||||
|
#define MATE_METHOD_RETURN_NULL() return info.GetReturnValue().SetNull()
|
||||||
|
#define MATE_METHOD_RETURN(value) args.Return(value)
|
||||||
|
|
||||||
|
#define MATE_STRING_NEW_FROM_UTF8(isolate, data, length) \
|
||||||
|
v8::String::NewFromUtf8(isolate, data, v8::String::kNormalString, length)
|
||||||
|
#define MATE_STRING_NEW_SYMBOL(isolate, data, length) \
|
||||||
|
v8::String::NewFromUtf8(isolate, data, v8::String::kInternalizedString, length)
|
||||||
|
|
||||||
|
#define MATE_SET_INTERNAL_FIELD_POINTER(object, index, value) \
|
||||||
|
object->SetAlignedPointerInInternalField(index, value)
|
||||||
|
#define MATE_GET_INTERNAL_FIELD_POINTER(object, index) \
|
||||||
|
object->GetAlignedPointerFromInternalField(index)
|
||||||
|
|
||||||
|
#define MATE_PERSISTENT_INIT(isolate, handle, value) \
|
||||||
|
handle(isolate, value)
|
||||||
|
#define MATE_PERSISTENT_ASSIGN(type, isolate, handle, value) \
|
||||||
|
handle.Reset(isolate, value)
|
||||||
|
#define MATE_PERSISTENT_RESET(handle) \
|
||||||
|
handle.Reset()
|
||||||
|
#define MATE_PERSISTENT_TO_LOCAL(type, isolate, handle) \
|
||||||
|
v8::Local<type>::New(isolate, handle)
|
||||||
|
#define MATE_PERSISTENT_SET_WEAK(handle, parameter, callback) \
|
||||||
|
handle.SetWeak(parameter, callback)
|
||||||
|
|
||||||
|
#define MATE_WEAK_CALLBACK(name, v8_type, c_type) \
|
||||||
|
void name(const v8::WeakCallbackData<v8_type, c_type>& data)
|
||||||
|
#define MATE_WEAK_CALLBACK_INIT(c_type) \
|
||||||
|
c_type* self = data.GetParameter()
|
||||||
|
|
||||||
|
#else // Node 0.8 and 0.10
|
||||||
|
|
||||||
|
#define MATE_HANDLE_SCOPE(isolate) v8::HandleScope handle_scope
|
||||||
|
|
||||||
|
#define MATE_METHOD_ARGS_TYPE v8::Arguments
|
||||||
|
#define MATE_METHOD_RETURN_TYPE v8::Handle<v8::Value>
|
||||||
|
|
||||||
|
#define MATE_METHOD_RETURN_VALUE(value) return value
|
||||||
|
#define MATE_METHOD_RETURN_UNDEFINED() return v8::Undefined()
|
||||||
|
#define MATE_METHOD_RETURN_NULL() return v8::Null()
|
||||||
|
#define MATE_METHOD_RETURN(value) \
|
||||||
|
MATE_METHOD_RETURN_VALUE(ConvertToV8(args.isolate(), value))
|
||||||
|
|
||||||
|
#define MATE_STRING_NEW_FROM_UTF8(isolate, data, length) \
|
||||||
|
v8::String::New(data, length)
|
||||||
|
#define MATE_STRING_NEW_SYMBOL(isolate, data, length) \
|
||||||
|
v8::String::NewSymbol(data, length)
|
||||||
|
|
||||||
|
#define MATE_SET_INTERNAL_FIELD_POINTER(object, index, value) \
|
||||||
|
object->SetPointerInInternalField(index, value)
|
||||||
|
#define MATE_GET_INTERNAL_FIELD_POINTER(object, index) \
|
||||||
|
object->GetPointerFromInternalField(index)
|
||||||
|
|
||||||
|
#define MATE_PERSISTENT_INIT(isolate, handle, value) \
|
||||||
|
handle(value)
|
||||||
|
#define MATE_PERSISTENT_ASSIGN(type, isolate, handle, value) \
|
||||||
|
handle = v8::Persistent<type>::New(value)
|
||||||
|
#define MATE_PERSISTENT_RESET(handle) \
|
||||||
|
handle.Dispose(); \
|
||||||
|
handle.Clear()
|
||||||
|
#define MATE_PERSISTENT_TO_LOCAL(type, isolate, handle) \
|
||||||
|
v8::Local<type>::New(handle)
|
||||||
|
#define MATE_PERSISTENT_SET_WEAK(handle, parameter, callback) \
|
||||||
|
handle.MakeWeak(parameter, callback)
|
||||||
|
|
||||||
|
#define MATE_WEAK_CALLBACK(name, v8_type, c_type) \
|
||||||
|
void name(v8::Persistent<v8::Value> object, void* parameter)
|
||||||
|
#define MATE_WEAK_CALLBACK_INIT(c_type) \
|
||||||
|
c_type* self = static_cast<c_type*>(parameter)
|
||||||
|
|
||||||
|
#endif // (NODE_MODULE_VERSION > 0x000B)
|
||||||
|
|
||||||
|
|
||||||
|
// Generally we should not provide utility macros, but this just makes things
|
||||||
|
// much more comfortable so we keep it.
|
||||||
|
#define MATE_METHOD(name) \
|
||||||
|
MATE_METHOD_RETURN_TYPE name(const MATE_METHOD_ARGS_TYPE& info)
|
||||||
|
|
||||||
|
// In lastest V8 ThrowException would need to pass isolate, be prepared for it.
|
||||||
|
#define MATE_THROW_EXCEPTION(isolate, value) \
|
||||||
|
v8::ThrowException(value)
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_COMPAT_H_
|
190
native_mate/converter.cc
Normal file
190
native_mate/converter.cc
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
#include "native_mate/compat.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
using v8::Boolean;
|
||||||
|
using v8::External;
|
||||||
|
using v8::Function;
|
||||||
|
using v8::Handle;
|
||||||
|
using v8::Integer;
|
||||||
|
using v8::Isolate;
|
||||||
|
using v8::Number;
|
||||||
|
using v8::Object;
|
||||||
|
using v8::String;
|
||||||
|
using v8::Value;
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
Handle<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) {
|
||||||
|
return Boolean::New(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<bool>::FromV8(Isolate* isolate, Handle<Value> val, bool* out) {
|
||||||
|
*out = val->BooleanValue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) {
|
||||||
|
return Integer::New(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<int32_t>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
int32_t* out) {
|
||||||
|
if (!val->IsInt32())
|
||||||
|
return false;
|
||||||
|
*out = val->Int32Value();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<uint32_t>::ToV8(Isolate* isolate, uint32_t val) {
|
||||||
|
return Integer::NewFromUnsigned(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<uint32_t>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
uint32_t* out) {
|
||||||
|
if (!val->IsUint32())
|
||||||
|
return false;
|
||||||
|
*out = val->Uint32Value();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<int64_t>::ToV8(Isolate* isolate, int64_t val) {
|
||||||
|
return Number::New(static_cast<double>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<int64_t>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
int64_t* out) {
|
||||||
|
if (!val->IsNumber())
|
||||||
|
return false;
|
||||||
|
// Even though IntegerValue returns int64_t, JavaScript cannot represent
|
||||||
|
// the full precision of int64_t, which means some rounding might occur.
|
||||||
|
*out = val->IntegerValue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) {
|
||||||
|
return Number::New(static_cast<double>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<uint64_t>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
uint64_t* out) {
|
||||||
|
if (!val->IsNumber())
|
||||||
|
return false;
|
||||||
|
*out = static_cast<uint64_t>(val->IntegerValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<float>::ToV8(Isolate* isolate, float val) {
|
||||||
|
return Number::New(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<float>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
float* out) {
|
||||||
|
if (!val->IsNumber())
|
||||||
|
return false;
|
||||||
|
*out = static_cast<float>(val->NumberValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<double>::ToV8(Isolate* isolate, double val) {
|
||||||
|
return Number::New(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<double>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
double* out) {
|
||||||
|
if (!val->IsNumber())
|
||||||
|
return false;
|
||||||
|
*out = val->NumberValue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<base::StringPiece>::ToV8(
|
||||||
|
Isolate* isolate, const base::StringPiece& val) {
|
||||||
|
return MATE_STRING_NEW_FROM_UTF8(isolate, val.data(),
|
||||||
|
static_cast<uint32_t>(val.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<std::string>::ToV8(Isolate* isolate,
|
||||||
|
const std::string& val) {
|
||||||
|
return Converter<base::StringPiece>::ToV8(isolate, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<std::string>::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
std::string* out) {
|
||||||
|
if (!val->IsString())
|
||||||
|
return false;
|
||||||
|
Handle<String> str = Handle<String>::Cast(val);
|
||||||
|
int length = str->Utf8Length();
|
||||||
|
out->resize(length);
|
||||||
|
str->WriteUtf8(&(*out)[0], length, NULL, String::NO_NULL_TERMINATION);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<Handle<Function> >::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
Handle<Function>* out) {
|
||||||
|
if (!val->IsFunction())
|
||||||
|
return false;
|
||||||
|
*out = Handle<Function>::Cast(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<Handle<Object> >::ToV8(Isolate* isolate,
|
||||||
|
Handle<Object> val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<Handle<Object> >::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
Handle<Object>* out) {
|
||||||
|
if (!val->IsObject())
|
||||||
|
return false;
|
||||||
|
*out = Handle<Object>::Cast(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<Handle<External> >::ToV8(Isolate* isolate,
|
||||||
|
Handle<External> val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<Handle<External> >::FromV8(Isolate* isolate,
|
||||||
|
v8::Handle<Value> val,
|
||||||
|
Handle<External>* out) {
|
||||||
|
if (!val->IsExternal())
|
||||||
|
return false;
|
||||||
|
*out = Handle<External>::Cast(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Value> Converter<Handle<Value> >::ToV8(Isolate* isolate,
|
||||||
|
Handle<Value> val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<Handle<Value> >::FromV8(Isolate* isolate, Handle<Value> val,
|
||||||
|
Handle<Value>* out) {
|
||||||
|
*out = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
|
||||||
|
const base::StringPiece& val) {
|
||||||
|
return MATE_STRING_NEW_SYMBOL(isolate,
|
||||||
|
val.data(),
|
||||||
|
static_cast<uint32_t>(val.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string V8ToString(v8::Handle<v8::Value> value) {
|
||||||
|
if (value.IsEmpty())
|
||||||
|
return std::string();
|
||||||
|
std::string result;
|
||||||
|
if (!ConvertFromV8(NULL, value, &result))
|
||||||
|
return std::string();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
193
native_mate/converter.h
Normal file
193
native_mate/converter.h
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_CONVERTER_H_
|
||||||
|
#define NATIVE_MATE_CONVERTER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/strings/string_piece.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
template<typename T, typename Enable = void>
|
||||||
|
struct Converter {};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<bool> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
bool val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
bool* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<int32_t> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
int32_t val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
int32_t* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<uint32_t> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
uint32_t val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
uint32_t* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<int64_t> {
|
||||||
|
// Warning: JavaScript cannot represent 64 integers precisely.
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
int64_t val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
int64_t* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<uint64_t> {
|
||||||
|
// Warning: JavaScript cannot represent 64 integers precisely.
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
uint64_t val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
uint64_t* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<float> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
float val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
float* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<double> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
double val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
double* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<base::StringPiece> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const base::StringPiece& val);
|
||||||
|
// No conversion out is possible because StringPiece does not contain storage.
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<std::string> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const std::string& val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
std::string* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<v8::Handle<v8::Function> > {
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
v8::Handle<v8::Function>* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<v8::Handle<v8::Object> > {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Object> val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
v8::Handle<v8::Object>* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<v8::Handle<v8::External> > {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::External> val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
v8::Handle<v8::External>* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<v8::Handle<v8::Value> > {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
v8::Handle<v8::Value>* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Converter<std::vector<T> > {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const std::vector<T>& val) {
|
||||||
|
v8::Handle<v8::Array> result(
|
||||||
|
v8::Array::New(static_cast<int>(val.size())));
|
||||||
|
for (size_t i = 0; i < val.size(); ++i) {
|
||||||
|
result->Set(static_cast<int>(i), Converter<T>::ToV8(isolate, val[i]));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
std::vector<T>* out) {
|
||||||
|
if (!val->IsArray())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<T> result;
|
||||||
|
v8::Handle<v8::Array> array(v8::Handle<v8::Array>::Cast(val));
|
||||||
|
uint32_t length = array->Length();
|
||||||
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
|
T item;
|
||||||
|
if (!Converter<T>::FromV8(isolate, array->Get(i), &item))
|
||||||
|
return false;
|
||||||
|
result.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
out->swap(result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convenience functions that deduce T.
|
||||||
|
template<typename T>
|
||||||
|
v8::Handle<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
||||||
|
T input) {
|
||||||
|
return Converter<T>::ToV8(isolate, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v8::Handle<v8::String> StringToV8(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
const base::StringPiece& input) {
|
||||||
|
return ConvertToV8(isolate, input).As<v8::String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
|
||||||
|
const base::StringPiece& val);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool ConvertFromV8(v8::Isolate* isolate, v8::Handle<v8::Value> input,
|
||||||
|
T* result) {
|
||||||
|
return Converter<T>::FromV8(isolate, input, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string V8ToString(v8::Handle<v8::Value> value);
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_CONVERTER_H_
|
42
native_mate/dictionary.cc
Normal file
42
native_mate/dictionary.cc
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
Dictionary::Dictionary(v8::Isolate* isolate)
|
||||||
|
: isolate_(isolate) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Dictionary(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Object> object)
|
||||||
|
: isolate_(isolate),
|
||||||
|
object_(object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::~Dictionary() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary Dictionary::CreateEmpty(v8::Isolate* isolate) {
|
||||||
|
Dictionary dictionary(isolate);
|
||||||
|
dictionary.object_ = v8::Object::New();
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::Value> Converter<Dictionary>::ToV8(v8::Isolate* isolate,
|
||||||
|
Dictionary val) {
|
||||||
|
return val.object_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Converter<Dictionary>::FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
Dictionary* out) {
|
||||||
|
if (!val->IsObject())
|
||||||
|
return false;
|
||||||
|
*out = Dictionary(isolate, v8::Handle<v8::Object>::Cast(val));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
64
native_mate/dictionary.h
Normal file
64
native_mate/dictionary.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_DICTIONARY_H_
|
||||||
|
#define NATIVE_MATE_DICTIONARY_H_
|
||||||
|
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
// Dictionary is useful when writing bindings for a function that either
|
||||||
|
// receives an arbitrary JavaScript object as an argument or returns an
|
||||||
|
// arbitrary JavaScript object as a result. For example, Dictionary is useful
|
||||||
|
// when you might use the |dictionary| type in WebIDL:
|
||||||
|
//
|
||||||
|
// http://heycam.github.io/webidl/#idl-dictionaries
|
||||||
|
//
|
||||||
|
// WARNING: You cannot retain a Dictionary object in the heap. The underlying
|
||||||
|
// storage for Dictionary is tied to the closest enclosing
|
||||||
|
// v8::HandleScope. Generally speaking, you should store a Dictionary
|
||||||
|
// on the stack.
|
||||||
|
//
|
||||||
|
class Dictionary {
|
||||||
|
public:
|
||||||
|
explicit Dictionary(v8::Isolate* isolate);
|
||||||
|
Dictionary(v8::Isolate* isolate, v8::Handle<v8::Object> object);
|
||||||
|
~Dictionary();
|
||||||
|
|
||||||
|
static Dictionary CreateEmpty(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool Get(const std::string& key, T* out) {
|
||||||
|
v8::Handle<v8::Value> val = object_->Get(StringToV8(isolate_, key));
|
||||||
|
return ConvertFromV8(isolate_, val, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool Set(const std::string& key, T val) {
|
||||||
|
return object_->Set(StringToV8(isolate_, key), ConvertToV8(isolate_, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Isolate* isolate() const { return isolate_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend struct Converter<Dictionary>;
|
||||||
|
|
||||||
|
// TODO(aa): Remove this. Instead, get via FromV8(), Set(), and Get().
|
||||||
|
v8::Isolate* isolate_;
|
||||||
|
v8::Handle<v8::Object> object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<Dictionary> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
Dictionary val);
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
Dictionary* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_DICTIONARY_H_
|
35
native_mate/function_template.cc
Normal file
35
native_mate/function_template.cc
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/function_template.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
CallbackHolderBase::CallbackHolderBase(v8::Isolate* isolate)
|
||||||
|
: MATE_PERSISTENT_INIT(isolate, v8_ref_, v8::External::New(isolate)) {
|
||||||
|
MATE_PERSISTENT_SET_WEAK(v8_ref_, this, &CallbackHolderBase::WeakCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
CallbackHolderBase::~CallbackHolderBase() {
|
||||||
|
DCHECK(v8_ref_.IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::External> CallbackHolderBase::GetHandle(v8::Isolate* isolate) {
|
||||||
|
return MATE_PERSISTENT_TO_LOCAL(v8::External, isolate, v8_ref_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
MATE_WEAK_CALLBACK(CallbackHolderBase::WeakCallback,
|
||||||
|
v8::External,
|
||||||
|
CallbackHolderBase) {
|
||||||
|
MATE_WEAK_CALLBACK_INIT(CallbackHolderBase);
|
||||||
|
MATE_PERSISTENT_RESET(self->v8_ref_);
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace mate
|
498
native_mate/function_template.h
Normal file
498
native_mate/function_template.h
Normal file
|
@ -0,0 +1,498 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_FUNCTION_TEMPLATE_H_
|
||||||
|
#define NATIVE_MATE_FUNCTION_TEMPLATE_H_
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "native_mate/arguments.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
class PerIsolateData;
|
||||||
|
|
||||||
|
enum CreateFunctionTemplateFlags {
|
||||||
|
HolderIsFirstArgument = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct CallbackParamTraits {
|
||||||
|
typedef T LocalType;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct CallbackParamTraits<const T&> {
|
||||||
|
typedef T LocalType;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct CallbackParamTraits<const T*> {
|
||||||
|
typedef T* LocalType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
|
||||||
|
// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
|
||||||
|
// DispatchToCallback, where it is invoked.
|
||||||
|
|
||||||
|
// This simple base class is used so that we can share a single object template
|
||||||
|
// among every CallbackHolder instance.
|
||||||
|
class CallbackHolderBase {
|
||||||
|
public:
|
||||||
|
v8::Handle<v8::External> GetHandle(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit CallbackHolderBase(v8::Isolate* isolate);
|
||||||
|
virtual ~CallbackHolderBase();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static MATE_WEAK_CALLBACK(WeakCallback, v8::External, CallbackHolderBase);
|
||||||
|
|
||||||
|
v8::Persistent<v8::External> v8_ref_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Sig>
|
||||||
|
class CallbackHolder : public CallbackHolderBase {
|
||||||
|
public:
|
||||||
|
CallbackHolder(v8::Isolate* isolate,
|
||||||
|
const base::Callback<Sig>& callback,
|
||||||
|
int flags)
|
||||||
|
: CallbackHolderBase(isolate), callback(callback), flags(flags) {}
|
||||||
|
base::Callback<Sig> callback;
|
||||||
|
int flags;
|
||||||
|
private:
|
||||||
|
virtual ~CallbackHolder() {}
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// This set of templates invokes a base::Callback, converts the return type to a
|
||||||
|
// JavaScript value, and returns that value to script via the provided
|
||||||
|
// mate::Arguments object.
|
||||||
|
//
|
||||||
|
// In C++, you can declare the function foo(void), but you can't pass a void
|
||||||
|
// expression to foo. As a result, we must specialize the case of Callbacks that
|
||||||
|
// have the void return type.
|
||||||
|
template<typename R, typename P1 = void, typename P2 = void,
|
||||||
|
typename P3 = void, typename P4 = void, typename P5 = void,
|
||||||
|
typename P6 = void>
|
||||||
|
struct Invoker {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4,
|
||||||
|
const P5& a5,
|
||||||
|
const P6& a6) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1, a2, a3, a4, a5, a6));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1, typename P2, typename P3, typename P4, typename P5,
|
||||||
|
typename P6>
|
||||||
|
struct Invoker<void, P1, P2, P3, P4, P5, P6> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4,
|
||||||
|
const P5& a5,
|
||||||
|
const P6& a6) {
|
||||||
|
callback.Run(a1, a2, a3, a4, a5, a6);
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3, typename P4,
|
||||||
|
typename P5>
|
||||||
|
struct Invoker<R, P1, P2, P3, P4, P5, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4,
|
||||||
|
const P5& a5) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1, a2, a3, a4, a5));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||||
|
struct Invoker<void, P1, P2, P3, P4, P5, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4,
|
||||||
|
const P5& a5) {
|
||||||
|
callback.Run(a1, a2, a3, a4, a5);
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3, typename P4>
|
||||||
|
struct Invoker<R, P1, P2, P3, P4, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1, P2, P3, P4)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1, a2, a3, a4));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1, typename P2, typename P3, typename P4>
|
||||||
|
struct Invoker<void, P1, P2, P3, P4, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1, P2, P3, P4)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3,
|
||||||
|
const P4& a4) {
|
||||||
|
callback.Run(a1, a2, a3, a4);
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3>
|
||||||
|
struct Invoker<R, P1, P2, P3, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1, P2, P3)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1, a2, a3));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1, typename P2, typename P3>
|
||||||
|
struct Invoker<void, P1, P2, P3, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1, P2, P3)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2,
|
||||||
|
const P3& a3) {
|
||||||
|
callback.Run(a1, a2, a3);
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2>
|
||||||
|
struct Invoker<R, P1, P2, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1, P2)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1, a2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1, typename P2>
|
||||||
|
struct Invoker<void, P1, P2, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1, P2)>& callback,
|
||||||
|
const P1& a1,
|
||||||
|
const P2& a2) {
|
||||||
|
callback.Run(a1, a2);
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1>
|
||||||
|
struct Invoker<R, P1, void, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R(P1)>& callback,
|
||||||
|
const P1& a1) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename P1>
|
||||||
|
struct Invoker<void, P1, void, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void(P1)>& callback,
|
||||||
|
const P1& a1) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run(a1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R>
|
||||||
|
struct Invoker<R, void, void, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<R()>& callback) {
|
||||||
|
MATE_METHOD_RETURN(callback.Run());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct Invoker<void, void, void, void, void, void, void> {
|
||||||
|
inline static MATE_METHOD_RETURN_TYPE Go(
|
||||||
|
Arguments& args,
|
||||||
|
const base::Callback<void()>& callback) {
|
||||||
|
callback.Run();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
|
||||||
|
T* result) {
|
||||||
|
if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
|
||||||
|
return args->GetHolder(result);
|
||||||
|
} else {
|
||||||
|
return args->GetNext(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For advanced use cases, we allow callers to request the unparsed Arguments
|
||||||
|
// object and poke around in it directly.
|
||||||
|
inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
|
||||||
|
Arguments* result) {
|
||||||
|
*result = *args;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
|
||||||
|
Arguments** result) {
|
||||||
|
*result = args;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's common for clients to just need the isolate, so we make that easy.
|
||||||
|
inline bool GetNextArgument(Arguments* args, int create_flags,
|
||||||
|
bool is_first, v8::Isolate** result) {
|
||||||
|
*result = args->isolate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DispatchToCallback converts all the JavaScript arguments to C++ types and
|
||||||
|
// invokes the base::Callback.
|
||||||
|
template<typename Sig>
|
||||||
|
struct Dispatcher {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R>
|
||||||
|
struct Dispatcher<R()> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R()> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
return Invoker<R>::Go(args, holder->callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1>
|
||||||
|
struct Dispatcher<R(P1)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1>::Go(args, holder->callback, a1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2>
|
||||||
|
struct Dispatcher<R(P1, P2)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1, P2)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
typename CallbackParamTraits<P2>::LocalType a2;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a2)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1, P2>::Go(args, holder->callback, a1, a2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3>
|
||||||
|
struct Dispatcher<R(P1, P2, P3)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1, P2, P3)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
typename CallbackParamTraits<P2>::LocalType a2;
|
||||||
|
typename CallbackParamTraits<P3>::LocalType a3;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a2) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a3)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1, P2, P3>::Go(args, holder->callback, a1, a2, a3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3, typename P4>
|
||||||
|
struct Dispatcher<R(P1, P2, P3, P4)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
typename CallbackParamTraits<P2>::LocalType a2;
|
||||||
|
typename CallbackParamTraits<P3>::LocalType a3;
|
||||||
|
typename CallbackParamTraits<P4>::LocalType a4;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a2) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a3) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a4)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1, P2, P3, P4>::Go(args, holder->callback, a1, a2, a3,
|
||||||
|
a4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3, typename P4,
|
||||||
|
typename P5>
|
||||||
|
struct Dispatcher<R(P1, P2, P3, P4, P5)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1, P2, P3, P4, P5)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
typename CallbackParamTraits<P2>::LocalType a2;
|
||||||
|
typename CallbackParamTraits<P3>::LocalType a3;
|
||||||
|
typename CallbackParamTraits<P4>::LocalType a4;
|
||||||
|
typename CallbackParamTraits<P5>::LocalType a5;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a2) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a3) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a4) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a5)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1, P2, P3, P4, P5>::Go(args, holder->callback, a1, a2,
|
||||||
|
a3, a4, a5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename R, typename P1, typename P2, typename P3, typename P4,
|
||||||
|
typename P5, typename P6>
|
||||||
|
struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
|
||||||
|
static MATE_METHOD(DispatchToCallback) {
|
||||||
|
Arguments args(info);
|
||||||
|
v8::Handle<v8::External> v8_holder;
|
||||||
|
CHECK(args.GetData(&v8_holder));
|
||||||
|
CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
||||||
|
v8_holder->Value());
|
||||||
|
|
||||||
|
typedef CallbackHolder<R(P1, P2, P3, P4, P5, P6)> HolderT;
|
||||||
|
HolderT* holder = static_cast<HolderT*>(holder_base);
|
||||||
|
|
||||||
|
typename CallbackParamTraits<P1>::LocalType a1;
|
||||||
|
typename CallbackParamTraits<P2>::LocalType a2;
|
||||||
|
typename CallbackParamTraits<P3>::LocalType a3;
|
||||||
|
typename CallbackParamTraits<P4>::LocalType a4;
|
||||||
|
typename CallbackParamTraits<P5>::LocalType a5;
|
||||||
|
typename CallbackParamTraits<P6>::LocalType a6;
|
||||||
|
if (!GetNextArgument(args, holder->flags, true, &a1) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a2) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a3) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a4) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a5) ||
|
||||||
|
!GetNextArgument(args, holder->flags, false, &a6)) {
|
||||||
|
args.ThrowError();
|
||||||
|
MATE_METHOD_RETURN_UNDEFINED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Invoker<R, P1, P2, P3, P4, P5, P6>::Go(args, holder->callback, a1,
|
||||||
|
a2, a3, a4, a5, a6);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
|
||||||
|
// JavaScript functions that execute a provided C++ function or base::Callback.
|
||||||
|
// JavaScript arguments are automatically converted via mate::Converter, as is
|
||||||
|
// the return value of the C++ function, if any.
|
||||||
|
template<typename Sig>
|
||||||
|
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
|
||||||
|
v8::Isolate* isolate, const base::Callback<Sig> callback,
|
||||||
|
int callback_flags = 0) {
|
||||||
|
typedef internal::CallbackHolder<Sig> HolderT;
|
||||||
|
HolderT* holder = new HolderT(isolate, callback, callback_flags);
|
||||||
|
|
||||||
|
return v8::FunctionTemplate::New(
|
||||||
|
isolate,
|
||||||
|
&internal::Dispatcher<Sig>::DispatchToCallback,
|
||||||
|
ConvertToV8<v8::Handle<v8::External> >(isolate,
|
||||||
|
holder->GetHandle(isolate)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_FUNCTION_TEMPLATE_H_
|
68
native_mate/handle.h
Normal file
68
native_mate/handle.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_HANDLE_H_
|
||||||
|
#define NATIVE_MATE_HANDLE_H_
|
||||||
|
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
// You can use mate::Handle on the stack to retain a mate::Wrappable object.
|
||||||
|
// Currently we don't have a mechanism for retaining a mate::Wrappable object
|
||||||
|
// in the C++ heap because strong references from C++ to V8 can cause memory
|
||||||
|
// leaks.
|
||||||
|
template<typename T>
|
||||||
|
class Handle {
|
||||||
|
public:
|
||||||
|
Handle() : object_(NULL) {}
|
||||||
|
|
||||||
|
Handle(v8::Handle<v8::Value> wrapper, T* object)
|
||||||
|
: wrapper_(wrapper),
|
||||||
|
object_(object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty() const { return !object_; }
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
wrapper_.Clear();
|
||||||
|
object_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const { return object_; }
|
||||||
|
v8::Handle<v8::Value> ToV8() const { return wrapper_; }
|
||||||
|
T* get() const { return object_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
v8::Handle<v8::Value> wrapper_;
|
||||||
|
T* object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Converter<mate::Handle<T> > {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const mate::Handle<T>& val) {
|
||||||
|
return val.ToV8();
|
||||||
|
}
|
||||||
|
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||||
|
mate::Handle<T>* out) {
|
||||||
|
T* object = NULL;
|
||||||
|
if (!Converter<T*>::FromV8(isolate, val, &object)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = mate::Handle<T>(val, object);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This function is a convenient way to create a handle from a raw pointer
|
||||||
|
// without having to write out the type of the object explicitly.
|
||||||
|
template<typename T>
|
||||||
|
mate::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) {
|
||||||
|
return mate::Handle<T>(object->GetWrapper(isolate), object);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_HANDLE_H_
|
39
native_mate/object_template_builder.cc
Normal file
39
native_mate/object_template_builder.cc
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/object_template_builder.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
|
||||||
|
: isolate_(isolate), template_(v8::ObjectTemplate::New()) {
|
||||||
|
template_->SetInternalFieldCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectTemplateBuilder::~ObjectTemplateBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(
|
||||||
|
const base::StringPiece& name, v8::Handle<v8::Data> val) {
|
||||||
|
template_->Set(StringToSymbol(isolate_, name), val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
|
||||||
|
const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter,
|
||||||
|
v8::Handle<v8::FunctionTemplate> setter) {
|
||||||
|
#if NODE_VERSION_AT_LEAST(0, 11, 0)
|
||||||
|
template_->SetAccessorProperty(StringToSymbol(isolate_, name), getter,
|
||||||
|
setter);
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
|
||||||
|
v8::Local<v8::ObjectTemplate> result = template_;
|
||||||
|
template_.Clear();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
123
native_mate/object_template_builder.h
Normal file
123
native_mate/object_template_builder.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_OBJECT_TEMPLATE_BUILDER_H_
|
||||||
|
#define NATIVE_MATE_OBJECT_TEMPLATE_BUILDER_H_
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/strings/string_piece.h"
|
||||||
|
#include "base/template_util.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
#include "native_mate/function_template.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Base template - used only for non-member function pointers. Other types
|
||||||
|
// either go to one of the below specializations, or go here and fail to compile
|
||||||
|
// because of base::Bind().
|
||||||
|
template<typename T, typename Enable = void>
|
||||||
|
struct CallbackTraits {
|
||||||
|
static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
|
||||||
|
T callback) {
|
||||||
|
return CreateFunctionTemplate(isolate, base::Bind(callback));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization for base::Callback.
|
||||||
|
template<typename T>
|
||||||
|
struct CallbackTraits<base::Callback<T> > {
|
||||||
|
static v8::Handle<v8::FunctionTemplate> CreateTemplate(
|
||||||
|
v8::Isolate* isolate, const base::Callback<T>& callback) {
|
||||||
|
return CreateFunctionTemplate(isolate, callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization for member function pointers. We need to handle this case
|
||||||
|
// specially because the first parameter for callbacks to MFP should typically
|
||||||
|
// come from the the JavaScript "this" object the function was called on, not
|
||||||
|
// from the first normal parameter.
|
||||||
|
template<typename T>
|
||||||
|
struct CallbackTraits<T, typename base::enable_if<
|
||||||
|
base::is_member_function_pointer<T>::value>::type> {
|
||||||
|
static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
|
||||||
|
T callback) {
|
||||||
|
return CreateFunctionTemplate(isolate, base::Bind(callback),
|
||||||
|
HolderIsFirstArgument);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This specialization allows people to construct function templates directly if
|
||||||
|
// they need to do fancier stuff.
|
||||||
|
template<>
|
||||||
|
struct CallbackTraits<v8::Handle<v8::FunctionTemplate> > {
|
||||||
|
static v8::Handle<v8::FunctionTemplate> CreateTemplate(
|
||||||
|
v8::Handle<v8::FunctionTemplate> templ) {
|
||||||
|
return templ;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
// ObjectTemplateBuilder provides a handy interface to creating
|
||||||
|
// v8::ObjectTemplate instances with various sorts of properties.
|
||||||
|
class ObjectTemplateBuilder {
|
||||||
|
public:
|
||||||
|
explicit ObjectTemplateBuilder(v8::Isolate* isolate);
|
||||||
|
~ObjectTemplateBuilder();
|
||||||
|
|
||||||
|
// It's against Google C++ style to return a non-const ref, but we take some
|
||||||
|
// poetic license here in order that all calls to Set() can be via the '.'
|
||||||
|
// operator and line up nicely.
|
||||||
|
template<typename T>
|
||||||
|
ObjectTemplateBuilder& SetValue(const base::StringPiece& name, T val) {
|
||||||
|
return SetImpl(name, ConvertToV8(isolate_, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the following methods, T and U can be function pointer, member function
|
||||||
|
// pointer, base::Callback, or v8::FunctionTemplate. Most clients will want to
|
||||||
|
// use one of the first two options. Also see mate::CreateFunctionTemplate()
|
||||||
|
// for creating raw function templates.
|
||||||
|
template<typename T>
|
||||||
|
ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
|
||||||
|
const T& callback) {
|
||||||
|
return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback));
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
|
||||||
|
const T& getter) {
|
||||||
|
return SetPropertyImpl(name,
|
||||||
|
CallbackTraits<T>::CreateTemplate(isolate_, getter),
|
||||||
|
v8::Local<v8::FunctionTemplate>());
|
||||||
|
}
|
||||||
|
template<typename T, typename U>
|
||||||
|
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
|
||||||
|
const T& getter, const U& setter) {
|
||||||
|
return SetPropertyImpl(name,
|
||||||
|
CallbackTraits<T>::CreateTemplate(isolate_, getter),
|
||||||
|
CallbackTraits<U>::CreateTemplate(isolate_, setter));
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::ObjectTemplate> Build();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
|
||||||
|
v8::Handle<v8::Data> val);
|
||||||
|
ObjectTemplateBuilder& SetPropertyImpl(
|
||||||
|
const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter,
|
||||||
|
v8::Handle<v8::FunctionTemplate> setter);
|
||||||
|
|
||||||
|
v8::Isolate* isolate_;
|
||||||
|
|
||||||
|
// ObjectTemplateBuilder should only be used on the stack.
|
||||||
|
v8::Local<v8::ObjectTemplate> template_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_OBJECT_TEMPLATE_BUILDER_H_
|
111
native_mate/scoped_persistent.h
Normal file
111
native_mate/scoped_persistent.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// Copyright 2014 Cheng Zhao. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license that can be found in the
|
||||||
|
// LICENSE file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_SCOPED_PERSISTENT_H_
|
||||||
|
#define NATIVE_MATE_SCOPED_PERSISTENT_H_
|
||||||
|
|
||||||
|
#include "base/memory/ref_counted.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
// A v8::Persistent handle to a V8 value which destroys and clears the
|
||||||
|
// underlying handle on destruction.
|
||||||
|
template <typename T>
|
||||||
|
class ScopedPersistent {
|
||||||
|
public:
|
||||||
|
ScopedPersistent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit ScopedPersistent(v8::Handle<T> handle) {
|
||||||
|
reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedPersistent() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(v8::Handle<T> handle) {
|
||||||
|
if (!handle.IsEmpty())
|
||||||
|
handle_.Reset(GetIsolate(handle), handle);
|
||||||
|
else
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
handle_.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty() const {
|
||||||
|
return handle_.IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<T> NewHandle() const {
|
||||||
|
if (handle_.IsEmpty())
|
||||||
|
return v8::Local<T>();
|
||||||
|
return v8::Local<T>::New(GetIsolate(handle_), handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<T> NewHandle(v8::Isolate* isolate) const {
|
||||||
|
if (handle_.IsEmpty())
|
||||||
|
return v8::Local<T>();
|
||||||
|
return v8::Local<T>::New(isolate, handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
void MakeWeak(P* parameters,
|
||||||
|
typename v8::WeakReferenceCallbacks<T, P>::Revivable callback) {
|
||||||
|
handle_.MakeWeak(parameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename U>
|
||||||
|
static v8::Isolate* GetIsolate(v8::Handle<U> object_handle) {
|
||||||
|
// Only works for v8::Object and its subclasses. Add specialisations for
|
||||||
|
// anything else.
|
||||||
|
if (!object_handle.IsEmpty())
|
||||||
|
return GetIsolate(object_handle->CreationContext());
|
||||||
|
return v8::Isolate::GetCurrent();
|
||||||
|
}
|
||||||
|
static v8::Isolate* GetIsolate(v8::Handle<v8::Context> context_handle) {
|
||||||
|
if (!context_handle.IsEmpty())
|
||||||
|
return context_handle->GetIsolate();
|
||||||
|
return v8::Isolate::GetCurrent();
|
||||||
|
}
|
||||||
|
static v8::Isolate* GetIsolate(
|
||||||
|
v8::Handle<v8::ObjectTemplate> template_handle) {
|
||||||
|
return v8::Isolate::GetCurrent();
|
||||||
|
}
|
||||||
|
template <typename U>
|
||||||
|
static v8::Isolate* GetIsolate(const U& any_handle) {
|
||||||
|
return v8::Isolate::GetCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Persistent<T> handle_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ScopedPersistent);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RefCountedPersistent : public ScopedPersistent<T>,
|
||||||
|
public base::RefCounted<RefCountedPersistent<T>> {
|
||||||
|
public:
|
||||||
|
RefCountedPersistent() {}
|
||||||
|
|
||||||
|
explicit RefCountedPersistent(v8::Handle<T> handle)
|
||||||
|
: ScopedPersistent<T>(handle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class base::RefCounted<RefCountedPersistent<T>>;
|
||||||
|
|
||||||
|
~RefCountedPersistent() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RefCountedPersistent);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_SCOPED_PERSISTENT_H_
|
49
native_mate/try_catch.cc
Normal file
49
native_mate/try_catch.cc
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/try_catch.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
TryCatch::TryCatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
TryCatch::~TryCatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TryCatch::HasCaught() {
|
||||||
|
return try_catch_.HasCaught();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TryCatch::GetStackTrace() {
|
||||||
|
if (!HasCaught()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
v8::Handle<v8::Message> message = try_catch_.Message();
|
||||||
|
ss << V8ToString(message->Get()) << std::endl
|
||||||
|
<< V8ToString(message->GetSourceLine()) << std::endl;
|
||||||
|
|
||||||
|
v8::Handle<v8::StackTrace> trace = message->GetStackTrace();
|
||||||
|
if (trace.IsEmpty())
|
||||||
|
return ss.str();
|
||||||
|
|
||||||
|
int len = trace->GetFrameCount();
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
v8::Handle<v8::StackFrame> frame = trace->GetFrame(i);
|
||||||
|
ss << V8ToString(frame->GetScriptName()) << ":"
|
||||||
|
<< frame->GetLineNumber() << ":"
|
||||||
|
<< frame->GetColumn() << ": "
|
||||||
|
<< V8ToString(frame->GetFunctionName())
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mate
|
32
native_mate/try_catch.h
Normal file
32
native_mate/try_catch.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_TRY_CATCH_H_
|
||||||
|
#define NATIVE_MATE_TRY_CATCH_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
// TryCatch is a convenient wrapper around v8::TryCatch.
|
||||||
|
class TryCatch {
|
||||||
|
public:
|
||||||
|
TryCatch();
|
||||||
|
~TryCatch();
|
||||||
|
|
||||||
|
bool HasCaught();
|
||||||
|
std::string GetStackTrace();
|
||||||
|
|
||||||
|
private:
|
||||||
|
v8::TryCatch try_catch_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(TryCatch);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_TRY_CATCH_H_
|
58
native_mate/wrappable.cc
Normal file
58
native_mate/wrappable.cc
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#include "native_mate/wrappable.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "native_mate/object_template_builder.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
Wrappable::Wrappable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Wrappable::~Wrappable() {
|
||||||
|
MATE_PERSISTENT_RESET(wrapper_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectTemplateBuilder Wrappable::GetObjectTemplateBuilder(
|
||||||
|
v8::Isolate* isolate) {
|
||||||
|
return ObjectTemplateBuilder(isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
MATE_WEAK_CALLBACK(Wrappable::WeakCallback, v8::Object, Wrappable) {
|
||||||
|
MATE_WEAK_CALLBACK_INIT(Wrappable);
|
||||||
|
MATE_PERSISTENT_RESET(self->wrapper_);
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Handle<v8::Object> Wrappable::GetWrapper(v8::Isolate* isolate) {
|
||||||
|
if (!wrapper_.IsEmpty()) {
|
||||||
|
return MATE_PERSISTENT_TO_LOCAL(v8::Object, isolate, wrapper_);
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::ObjectTemplate> templ =
|
||||||
|
GetObjectTemplateBuilder(isolate).Build();
|
||||||
|
CHECK(!templ.IsEmpty());
|
||||||
|
CHECK_EQ(1, templ->InternalFieldCount());
|
||||||
|
v8::Handle<v8::Object> wrapper = templ->NewInstance();
|
||||||
|
MATE_SET_INTERNAL_FIELD_POINTER(wrapper, 0, this);
|
||||||
|
MATE_PERSISTENT_ASSIGN(v8::Object, isolate, wrapper_, wrapper);
|
||||||
|
MATE_PERSISTENT_SET_WEAK(wrapper_, this, WeakCallback);
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
void* FromV8Impl(v8::Isolate* isolate, v8::Handle<v8::Value> val) {
|
||||||
|
if (!val->IsObject())
|
||||||
|
return NULL;
|
||||||
|
v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val);
|
||||||
|
return MATE_GET_INTERNAL_FIELD_POINTER(obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace mate
|
85
native_mate/wrappable.h
Normal file
85
native_mate/wrappable.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE.chromium file.
|
||||||
|
|
||||||
|
#ifndef NATIVE_MATE_WRAPPABLE_H_
|
||||||
|
#define NATIVE_MATE_WRAPPABLE_H_
|
||||||
|
|
||||||
|
#include "base/template_util.h"
|
||||||
|
#include "native_mate/compat.h"
|
||||||
|
#include "native_mate/converter.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
void* FromV8Impl(v8::Isolate* isolate, v8::Handle<v8::Value> val);
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
// Wrappable is a base class for C++ objects that have corresponding v8 wrapper
|
||||||
|
// objects. To retain a Wrappable object on the stack, use a mate::Handle.
|
||||||
|
//
|
||||||
|
// USAGE:
|
||||||
|
// // my_class.h
|
||||||
|
// class MyClass : Wrappable {
|
||||||
|
// public:
|
||||||
|
// // Optional, only required if non-empty template should be used.
|
||||||
|
// virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
// v8::Isolate* isolate);
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// mate::ObjectTemplateBuilder MyClass::GetObjectTemplateBuilder(
|
||||||
|
// v8::Isolate* isolate) {
|
||||||
|
// return Wrappable::GetObjectTemplateBuilder(isolate).SetValue("foobar", 42);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Subclasses should also typically have private constructors and expose a
|
||||||
|
// static Create function that returns a mate::Handle. Forcing creators through
|
||||||
|
// this static Create function will enforce that clients actually create a
|
||||||
|
// wrapper for the object. If clients fail to create a wrapper for a wrappable
|
||||||
|
// object, the object will leak because we use the weak callback from the
|
||||||
|
// wrapper as the signal to delete the wrapped object.
|
||||||
|
class ObjectTemplateBuilder;
|
||||||
|
|
||||||
|
// Non-template base class to share code between templates instances.
|
||||||
|
class Wrappable {
|
||||||
|
public:
|
||||||
|
// Retrieve (or create) the v8 wrapper object cooresponding to this object.
|
||||||
|
v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Wrappable();
|
||||||
|
virtual ~Wrappable();
|
||||||
|
|
||||||
|
virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static MATE_WEAK_CALLBACK(WeakCallback, v8::Object, Wrappable);
|
||||||
|
|
||||||
|
v8::Persistent<v8::Object> wrapper_; // Weak
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Wrappable);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// This converter handles any subclass of Wrappable.
|
||||||
|
template<typename T>
|
||||||
|
struct Converter<T*, typename base::enable_if<
|
||||||
|
base::is_convertible<T*, Wrappable*>::value>::type> {
|
||||||
|
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
|
||||||
|
return val->GetWrapper(isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, T** out) {
|
||||||
|
*out = static_cast<T*>(static_cast<Wrappable*>(
|
||||||
|
internal::FromV8Impl(isolate, val)));
|
||||||
|
return *out != NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // NATIVE_MATE_WRAPPABLE_H_
|
23
native_mate_files.gypi
Normal file
23
native_mate_files.gypi
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
'variables': {
|
||||||
|
'native_mate_files': [
|
||||||
|
'native_mate/arguments.cc',
|
||||||
|
'native_mate/arguments.h',
|
||||||
|
'native_mate/compat.h',
|
||||||
|
'native_mate/converter.cc',
|
||||||
|
'native_mate/converter.h',
|
||||||
|
'native_mate/dictionary.cc',
|
||||||
|
'native_mate/dictionary.h',
|
||||||
|
'native_mate/function_template.cc',
|
||||||
|
'native_mate/function_template.h',
|
||||||
|
'native_mate/handle.h',
|
||||||
|
'native_mate/object_template_builder.cc',
|
||||||
|
'native_mate/object_template_builder.h',
|
||||||
|
'native_mate/scoped_persistent.h',
|
||||||
|
'native_mate/try_catch.cc',
|
||||||
|
'native_mate/try_catch.h',
|
||||||
|
'native_mate/wrappable.cc',
|
||||||
|
'native_mate/wrappable.h',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue