Last active
December 17, 2015 23:39
-
-
Save AonekoSS/5691206 to your computer and use it in GitHub Desktop.
v8エンジンを変態チックにバインドしてみるテスト。Variadic Templateやら関数SFINAEやら使える環境なら、もうちとスマートに書ける筈なのだけど……orz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <type_traits> | |
using namespace v8; | |
//--------------------------------------------------------------------------- | |
// メタプロ用マクロとか | |
//--------------------------------------------------------------------------- | |
// 引数バリエーション | |
#define __A0__ | |
#define __A1__ A1 | |
#define __A2__ A1,A2 | |
#define __A3__ A1,A2,A3 | |
#define __A4__ A1,A2,A3,A4 | |
#define __A5__ A1,A2,A3,A4,A5 | |
#define __A6__ A1,A2,A3,A4,A5,A6 | |
#define __A7__ A1,A2,A3,A4,A5,A6,A7 | |
#define __A8__ A1,A2,A3,A4,A5,A6,A7,A8 | |
#define __V0__ | |
#define __V1__ CVal<A1>(a[0]) | |
#define __V2__ CVal<A1>(a[0]),CVal<A2>(a[1]) | |
#define __V3__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]) | |
#define __V4__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]),CVal<A4>(a[3]) | |
#define __V5__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]),CVal<A4>(a[3]),CVal<A5>(a[4]) | |
#define __V6__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]),CVal<A4>(a[3]),CVal<A5>(a[4]),CVal<A6>(a[5]) | |
#define __V7__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]),CVal<A4>(a[3]),CVal<A5>(a[4]),CVal<A6>(a[5]),CVal<A7>(a[6]) | |
#define __V8__ CVal<A1>(a[0]),CVal<A2>(a[1]),CVal<A3>(a[2]),CVal<A4>(a[3]),CVal<A5>(a[4]),CVal<A6>(a[5]),CVal<A7>(a[6]),CVal<A8>(a[7]) | |
#define __C0__ | |
#define __C1__ class A1 | |
#define __C2__ class A1,class A2 | |
#define __C3__ class A1,class A2,class A3 | |
#define __C4__ class A1,class A2,class A3,class A4 | |
#define __C5__ class A1,class A2,class A3,class A4,class A5 | |
#define __C6__ class A1,class A2,class A3,class A4,class A5,class A6 | |
#define __C7__ class A1,class A2,class A3,class A4,class A5,class A6,class A7 | |
#define __C8__ class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8 | |
// 共通要素 | |
#define __SCOPE__ HandleScope scope; | |
#define __CATCH__ catch(std::exception& e){ return ThrowException(Exception::Error(String::New(e.what()))); } | |
typedef Handle<Value> RES; | |
typedef Arguments const & ARG; | |
//--------------------------------------------------------------------------- | |
// C++オブジェクトへの変換 | |
//--------------------------------------------------------------------------- | |
template <class T> | |
inline T CVal(const Handle<Value>& v, typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr){ | |
if(std::is_same<T, bool>::value)return static_cast<T>(v->BooleanValue()); | |
if(std::is_unsigned<T>::value)return static_cast<T>(v->Uint32Value()); | |
if(std::is_integral<T>::value)return static_cast<T>(v->Int32Value()); | |
return static_cast<T>(v->NumberValue()); | |
}; | |
template <class T> | |
inline T CVal(const Handle<Value>& v, typename std::enable_if<std::is_same<T, std::string>::value>::type* = nullptr){ | |
return *String::AsciiValue(v); | |
} | |
template <class T> | |
inline T CVal(const Handle<Value>& v, typename std::enable_if<std::is_pointer<T>::value>::type* = nullptr){ | |
return static_cast<T>(Handle<External>::Cast(v)->Value()); | |
} | |
template <class T> | |
inline T CVal(const Handle<Value>& v, typename std::enable_if<std::is_member_pointer<T>::value>::type* = nullptr){ | |
return *static_cast<T*>(Handle<External>::Cast(v)->Value()); | |
} | |
//--------------------------------------------------------------------------- | |
// JavaScriptオブジェクトへの変換 | |
//--------------------------------------------------------------------------- | |
template <class T> | |
inline Handle<Value> JVal(T v){ | |
if(std::is_same<T, bool>::value)return Boolean::New(v!=false); | |
if(std::is_unsigned<T>::value)return Integer::NewFromUnsigned(v); | |
if(std::is_integral<T>::value)return Integer::New(v); | |
return Number::New(v); | |
} | |
template <class T> | |
inline Handle<Value> JVal(T* v){ | |
return External::New(v); | |
} | |
template <> | |
inline Handle<Value> JVal<const std::string&>(const std::string& v){ | |
return String::New(v.c_str()); | |
} | |
//--------------------------------------------------------------------------- | |
// C++オブジェクトのラッピング(クラスメンバへのポインタとか、void*より大きいの向け) | |
//--------------------------------------------------------------------------- | |
template <class T> | |
Persistent<External> Wrap(T *obj){ | |
Isolate *isolate = Isolate::GetCurrent(); | |
auto ext = Persistent<External>::New(isolate, External::New(obj)); | |
ext.MakeWeak(isolate, obj, Deleter<T>); | |
return ext; | |
} | |
template <class T> | |
void Deleter(Isolate *isolate, Persistent<Value> h, void* obj){ | |
delete static_cast<T*>(obj); | |
h.Dispose(isolate); | |
} | |
//--------------------------------------------------------------------------- | |
// 関数プロキシ郡(Variadic Templateが使えれば、もうちとスッキリする筈……) | |
//--------------------------------------------------------------------------- | |
// 通常関数 | |
template <class F> F GetF(ARG a){ return CVal<F>(a.Data()); } | |
template <class R> | |
struct FuncProxyT{ | |
template <class F __C0__> static RES F0(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V0__)); }__CATCH__ return Undefined(); } | |
template <class F,__C1__> static RES F1(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V1__)); }__CATCH__ return Undefined(); } | |
template <class F,__C2__> static RES F2(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V2__)); }__CATCH__ return Undefined(); } | |
template <class F,__C3__> static RES F3(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V3__)); }__CATCH__ return Undefined(); } | |
template <class F,__C4__> static RES F4(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V4__)); }__CATCH__ return Undefined(); } | |
template <class F,__C5__> static RES F5(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V5__)); }__CATCH__ return Undefined(); } | |
template <class F,__C6__> static RES F6(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V6__)); }__CATCH__ return Undefined(); } | |
template <class F,__C7__> static RES F7(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V7__)); }__CATCH__ return Undefined(); } | |
template <class F,__C8__> static RES F8(ARG a){ __SCOPE__ try{ return JVal(GetF<F>(a)(__V8__)); }__CATCH__ return Undefined(); } | |
}; | |
template <> | |
struct FuncProxyT<void>{ | |
template <class F __C0__> static RES F0(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V0__); }__CATCH__ return Undefined(); } | |
template <class F,__C1__> static RES F1(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V1__); }__CATCH__ return Undefined(); } | |
template <class F,__C2__> static RES F2(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V2__); }__CATCH__ return Undefined(); } | |
template <class F,__C3__> static RES F3(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V3__); }__CATCH__ return Undefined(); } | |
template <class F,__C4__> static RES F4(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V4__); }__CATCH__ return Undefined(); } | |
template <class F,__C5__> static RES F5(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V5__); }__CATCH__ return Undefined(); } | |
template <class F,__C6__> static RES F6(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V6__); }__CATCH__ return Undefined(); } | |
template <class F,__C7__> static RES F7(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V7__); }__CATCH__ return Undefined(); } | |
template <class F,__C8__> static RES F8(ARG a){ __SCOPE__ try{ GetF<F>(a)(__V8__); }__CATCH__ return Undefined(); } | |
}; | |
template <class R __C0__> InvocationCallback FunctionProxy(R f(__A0__)){ return FuncProxyT<R>::F0<R(*)(__A0__) __A0__>; } | |
template <class R,__C1__> InvocationCallback FunctionProxy(R f(__A1__)){ return FuncProxyT<R>::F1<R(*)(__A1__),__A1__>; } | |
template <class R,__C2__> InvocationCallback FunctionProxy(R f(__A2__)){ return FuncProxyT<R>::F2<R(*)(__A2__),__A2__>; } | |
template <class R,__C3__> InvocationCallback FunctionProxy(R f(__A3__)){ return FuncProxyT<R>::F3<R(*)(__A3__),__A3__>; } | |
template <class R,__C4__> InvocationCallback FunctionProxy(R f(__A4__)){ return FuncProxyT<R>::F4<R(*)(__A4__),__A4__>; } | |
template <class R,__C5__> InvocationCallback FunctionProxy(R f(__A5__)){ return FuncProxyT<R>::F5<R(*)(__A5__),__A5__>; } | |
template <class R,__C6__> InvocationCallback FunctionProxy(R f(__A6__)){ return FuncProxyT<R>::F6<R(*)(__A6__),__A6__>; } | |
template <class R,__C7__> InvocationCallback FunctionProxy(R f(__A7__)){ return FuncProxyT<R>::F7<R(*)(__A7__),__A7__>; } | |
template <class R,__C8__> InvocationCallback FunctionProxy(R f(__A8__)){ return FuncProxyT<R>::F8<R(*)(__A8__),__A8__>; } | |
// メンバー関数 | |
template <class C> C* GetI(ARG a){ return CVal<C*>(a.This()->GetInternalField(0)); } | |
template <class M> M GetM(ARG a){ return *CVal<M*>(a.Data()); } | |
template <class C, class R> | |
struct MethodProxyT{ | |
template <class M __C0__> static RES F0(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V0__)); }__CATCH__ return Undefined(); } | |
template <class M,__C1__> static RES F1(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V1__)); }__CATCH__ return Undefined(); } | |
template <class M,__C2__> static RES F2(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V2__)); }__CATCH__ return Undefined(); } | |
template <class M,__C3__> static RES F3(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V3__)); }__CATCH__ return Undefined(); } | |
template <class M,__C4__> static RES F4(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V4__)); }__CATCH__ return Undefined(); } | |
template <class M,__C5__> static RES F5(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V5__)); }__CATCH__ return Undefined(); } | |
template <class M,__C6__> static RES F6(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V6__)); }__CATCH__ return Undefined(); } | |
template <class M,__C7__> static RES F7(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V7__)); }__CATCH__ return Undefined(); } | |
template <class M,__C8__> static RES F8(ARG a){ __SCOPE__ try{ return JVal((GetI<C>(a)->*GetM<M>(a))(__V8__)); }__CATCH__ return Undefined(); } | |
}; | |
template <class C> | |
struct MethodProxyT<C,void>{ | |
template <class M __C0__> static RES F0(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V0__); }__CATCH__ return Undefined(); } | |
template <class M,__C1__> static RES F1(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V1__); }__CATCH__ return Undefined(); } | |
template <class M,__C2__> static RES F2(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V2__); }__CATCH__ return Undefined(); } | |
template <class M,__C3__> static RES F3(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V3__); }__CATCH__ return Undefined(); } | |
template <class M,__C4__> static RES F4(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V4__); }__CATCH__ return Undefined(); } | |
template <class M,__C5__> static RES F5(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V5__); }__CATCH__ return Undefined(); } | |
template <class M,__C6__> static RES F6(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V6__); }__CATCH__ return Undefined(); } | |
template <class M,__C7__> static RES F7(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V7__); }__CATCH__ return Undefined(); } | |
template <class M,__C8__> static RES F8(ARG a){ __SCOPE__ try{ (GetI<C>(a)->*GetM<M>(a))(__V8__); }__CATCH__ return Undefined(); } | |
}; | |
template <class C,class R __C0__> InvocationCallback MethodProxy(R(C::*m)(__A0__)){ return MethodProxyT<C,R>::F0<R(C::*)(__A0__) __A0__>; } | |
template <class C,class R,__C1__> InvocationCallback MethodProxy(R(C::*m)(__A1__)){ return MethodProxyT<C,R>::F1<R(C::*)(__A1__),__A1__>; } | |
template <class C,class R,__C2__> InvocationCallback MethodProxy(R(C::*m)(__A2__)){ return MethodProxyT<C,R>::F2<R(C::*)(__A2__),__A2__>; } | |
template <class C,class R,__C3__> InvocationCallback MethodProxy(R(C::*m)(__A3__)){ return MethodProxyT<C,R>::F3<R(C::*)(__A3__),__A3__>; } | |
template <class C,class R,__C4__> InvocationCallback MethodProxy(R(C::*m)(__A4__)){ return MethodProxyT<C,R>::F4<R(C::*)(__A4__),__A4__>; } | |
template <class C,class R,__C5__> InvocationCallback MethodProxy(R(C::*m)(__A5__)){ return MethodProxyT<C,R>::F5<R(C::*)(__A5__),__A5__>; } | |
template <class C,class R,__C6__> InvocationCallback MethodProxy(R(C::*m)(__A6__)){ return MethodProxyT<C,R>::F6<R(C::*)(__A6__),__A6__>; } | |
template <class C,class R,__C7__> InvocationCallback MethodProxy(R(C::*m)(__A7__)){ return MethodProxyT<C,R>::F7<R(C::*)(__A7__),__A7__>; } | |
template <class C,class R,__C8__> InvocationCallback MethodProxy(R(C::*m)(__A8__)){ return MethodProxyT<C,R>::F8<R(C::*)(__A8__),__A8__>; } | |
// コンストラクター | |
template <class C __C0__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V0__))); return a.This(); } | |
template <class C,__C1__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V1__))); return a.This(); } | |
template <class C,__C2__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V2__))); return a.This(); } | |
template <class C,__C3__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V3__))); return a.This(); } | |
template <class C,__C4__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V4__))); return a.This(); } | |
template <class C,__C5__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V5__))); return a.This(); } | |
template <class C,__C6__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V6__))); return a.This(); } | |
template <class C,__C7__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V7__))); return a.This(); } | |
template <class C,__C8__> RES CtorProxy(ARG a){ __SCOPE__ a.This()->SetInternalField(0, Wrap(new C(__V8__))); return a.This(); } | |
//--------------------------------------------------------------------------- | |
// クラス | |
//--------------------------------------------------------------------------- | |
template <class C> | |
class Class{ | |
friend class JavaScript; | |
public: | |
Class(){ | |
handle = FunctionTemplate::New(CtorProxy<C>); | |
handle->SetClassName(String::New(typeid(C).name())); | |
handle->InstanceTemplate()->SetInternalFieldCount(1); | |
} | |
~Class(){} | |
// コンストラクタ定義(Variadic Templateが……略) | |
template <__C1__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A1__>); } | |
template <__C2__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A2__>); } | |
template <__C3__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A3__>); } | |
template <__C4__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A4__>); } | |
template <__C5__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A5__>); } | |
template <__C6__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A6__>); } | |
template <__C7__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A7__>); } | |
template <__C8__> void Constructor(){ handle->SetCallHandler(CtorProxy<C, __A8__>); } | |
// アクセサ | |
class Accessor{ | |
public: | |
Accessor(Local<ObjectTemplate> methods, Local<ObjectTemplate> objects, const std::string& name): | |
methods_(methods), objects_(objects), name_(name){} | |
// メンバ関数バインド | |
template <class T> | |
Accessor& operator <= (T C::*method){ | |
typedef decltype(method) P; | |
static_assert(std::is_member_function_pointer<P>::value,"must be member function"); | |
HandleScope scope; | |
methods_->Set(name_.c_str(), FunctionTemplate::New(MethodProxy(method), Wrap(new P(method)))); | |
return *this; | |
} | |
// メンバ変数バインド | |
template <class T> | |
Accessor& operator = (T C::*object){ | |
typedef decltype(object) P; | |
static_assert(std::is_member_object_pointer<P>::value,"must be member object"); | |
HandleScope scope; | |
objects_->SetAccessor(String::New(name_.c_str()), Getter<T>, Setter<T>, Wrap(new P(object))); | |
return *this; | |
} | |
private: | |
Local<ObjectTemplate> methods_; | |
Local<ObjectTemplate> objects_; | |
const std::string& name_; | |
}; | |
Accessor operator[](const std::string& name){ | |
return Accessor(handle->PrototypeTemplate(), handle->InstanceTemplate(), name); | |
} | |
private: | |
Local<FunctionTemplate> handle; | |
template <class T> | |
static Handle<Value> Getter(Local<String> name, const AccessorInfo& info){ | |
C* instance = CVal<C*>(info.Holder()->GetInternalField(0)); | |
T C::*pointer = CVal<T C::*>(info.Data()); | |
return JVal(instance->*pointer); | |
} | |
template <class T> | |
static void Setter(Local<String> name, Local<Value> value, const AccessorInfo& info){ | |
C* instance = CVal<C*>(info.Holder()->GetInternalField(0)); | |
T C::*pointer = CVal<T C::*>(info.Data()); | |
instance->*pointer = CVal<T>(value); | |
} | |
}; | |
//--------------------------------------------------------------------------- | |
// 実行環境 | |
//--------------------------------------------------------------------------- | |
class JavaScript{ | |
public: | |
JavaScript() : global(ObjectTemplate::New()){} | |
~JavaScript(){} | |
// 実行 | |
bool Execute(const std::string& code, const std::string& name=""){ | |
HandleScope scope; | |
Local<Context> context = Context::New(Isolate::GetCurrent(), 0, global); | |
Context::Scope cscope(context); | |
TryCatch trycatch; | |
Local<Script> script = Script::Compile(String::New(code.c_str()), String::New(name.c_str())); | |
if( script.IsEmpty() ){ Catch(trycatch); return false; } | |
Local<Value> result = script->Run(); | |
if( result.IsEmpty() ){ Catch(trycatch); return false; } | |
return true; | |
} | |
// アクセサ | |
class Accessor{ | |
public: | |
Accessor(Local<ObjectTemplate> table, const std::string& name): | |
table_(table), name_(name){} | |
// 関数バインド | |
template <class F> | |
Accessor& operator <= (F func){ | |
static_assert(std::is_function<std::remove_pointer<F>::type>::value,"must be function"); | |
HandleScope scope; | |
table_->Set(name_.c_str(), FunctionTemplate::New(FunctionProxy(func), External::New(func))); | |
return *this; | |
} | |
// クラスバインド | |
template <class C> | |
Accessor& operator = (const Class<C>& cls){ | |
HandleScope scope; | |
cls.handle->SetClassName(String::New(name_.c_str())); | |
table_->Set(name_.c_str(), cls.handle); | |
return *this; | |
} | |
private: | |
Local<ObjectTemplate> table_; | |
const std::string& name_; | |
}; | |
Accessor operator[](const std::string& name){ | |
return Accessor(global, name); | |
} | |
private: | |
HandleScope handle_scope; | |
Local<ObjectTemplate> global; | |
// 例外キャッチ | |
static void Catch(TryCatch& trycatch) { | |
HandleScope scope; | |
std::string message = CVal<std::string>(trycatch.Exception()); | |
Local<Message> info = trycatch.Message(); | |
if(info.IsEmpty()){ | |
std::cerr << message << std::endl; | |
}else{ | |
std::string name = CVal<std::string>(info->GetScriptResourceName()); | |
std::string code = CVal<std::string>(info->GetSourceLine()); | |
int line = info->GetLineNumber(); | |
int start = info->GetStartColumn(); | |
int end = info->GetEndColumn(); | |
std::cerr << name << "[" << line << "] " << message << std::endl; | |
std::cerr << code << std::endl << std::string(start,' ') << std::string(end-start,'^') << std::endl; | |
} | |
} | |
}; | |
//--------------------------------------------------------------------------- | |
// マクロの後始末 | |
//--------------------------------------------------------------------------- | |
#undef __A0__ | |
#undef __A1__ | |
#undef __A2__ | |
#undef __A3__ | |
#undef __A4__ | |
#undef __A5__ | |
#undef __A6__ | |
#undef __A7__ | |
#undef __A8__ | |
#undef __V0__ | |
#undef __V1__ | |
#undef __V2__ | |
#undef __V3__ | |
#undef __V4__ | |
#undef __V5__ | |
#undef __V6__ | |
#undef __V7__ | |
#undef __V8__ | |
#undef __C0__ | |
#undef __C1__ | |
#undef __C2__ | |
#undef __C3__ | |
#undef __C4__ | |
#undef __C5__ | |
#undef __C6__ | |
#undef __C7__ | |
#undef __C8__ | |
#undef __SCOPE__ | |
#undef __CATCH__ | |
//--------------------------------------------------------------------------- | |
// 以下、テスト用コード | |
//--------------------------------------------------------------------------- | |
// テスト用関数 | |
void Test(){ std::cout << "Test()" << std::endl; } | |
void Test2(int a){ std::cout << "Test2(" << a << ")" << std::endl; } | |
void Test3(std::string s){ std::cout << "Test3(" << s << ")" << std::endl; } | |
// テスト用クラス | |
class Hoge{ | |
public: | |
~Hoge(){ std::cout << "Hoge デストラクタ" << std::endl; } | |
Hoge(){ std::cout << "Hoge コンストラクタ(デフォルト)" << std::endl; } | |
Hoge(int a){ std::cout << "Hoge コンストラクタ(" << a << ")" << std::endl; } | |
void Test(int a){ std::cout << "Hoge::Test(" << a << ")" << std::endl; } | |
int value; | |
}; | |
void run(){ | |
// テストコード | |
const char* name = "test_script.txt"; | |
const char* code = | |
"test()\n" | |
"test2(999)\n" | |
"test3(\"abcdefg\"))\n" | |
"var hoge=new Hoge(123)\n" | |
"hoge.Test(234)\n" | |
"hoge.value=12\n"; | |
// グローバル関数のバインド | |
JavaScript js; | |
js["test"] <= Test; | |
js["test2"]<= Test2; | |
js["test3"]<= Test3; | |
// クラスのバインド | |
Class<Hoge> cls; | |
cls.Constructor<int>(); // コンストラクタ定義 | |
cls["Test"] <= &Hoge::Test; // メンバ関数 | |
cls["value"] = &Hoge::value; // メンバ変数 | |
// クラス登録 | |
js["Hoge"] = cls; | |
// 実行 | |
js.Execute(code,name); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment