| Index: gin/function_template.h.pump
|
| diff --git a/gin/function_template.h.pump b/gin/function_template.h.pump
|
| index 6b6ffc57e4ac57db98c530affd689f3cef07d36e..441313ae3010454aaea8a99d0f24c20b19864433 100644
|
| --- a/gin/function_template.h.pump
|
| +++ b/gin/function_template.h.pump
|
| @@ -28,6 +28,10 @@ namespace gin {
|
|
|
| class PerIsolateData;
|
|
|
| +enum CreateFunctionTemplateFlags {
|
| + HolderIsFirstArgument = 1 << 0,
|
| +};
|
| +
|
| namespace internal {
|
|
|
| template<typename T>
|
| @@ -38,6 +42,10 @@ template<typename T>
|
| struct RemoveConstRef<const T&> {
|
| typedef T Type;
|
| };
|
| +template<typename T>
|
| +struct RemoveConstRef<const T*> {
|
| + typedef T* Type;
|
| +};
|
|
|
|
|
| // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
|
| @@ -60,9 +68,10 @@ class CallbackHolderBase : public Wrappable {
|
| template<typename Sig>
|
| class CallbackHolder : public CallbackHolderBase {
|
| public:
|
| - CallbackHolder(const base::Callback<Sig>& callback)
|
| - : callback(callback) {}
|
| + CallbackHolder(const base::Callback<Sig>& callback, int flags)
|
| + : callback(callback), flags(flags) {}
|
| base::Callback<Sig> callback;
|
| + int flags;
|
| private:
|
| virtual ~CallbackHolder() {}
|
| };
|
| @@ -110,39 +119,63 @@ struct Invoker<void$for ARG [[, P$(ARG)]]$for VOID [[, void]]> {
|
|
|
| ]]
|
|
|
| +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 flags, bool is_first,
|
| + Arguments* result) {
|
| + *result = *args;
|
| + return true;
|
| +}
|
| +
|
| +
|
| // DispatchToCallback converts all the JavaScript arguments to C++ types and
|
| // invokes the base::Callback.
|
| +template<typename Sig>
|
| +struct Dispatcher {
|
| +};
|
| +
|
| $range ARITY 0..MAX_ARITY
|
| $for ARITY [[
|
| $range ARG 1..ARITY
|
|
|
| template<typename R$for ARG [[, typename P$(ARG)]]>
|
| -static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - CallbackHolderBase* holder_base = NULL;
|
| - CHECK(args.GetData(&holder_base));
|
| +struct Dispatcher<R($for ARG , [[P$(ARG)]])> {
|
| + static void DispatchToCallback(
|
| + const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| + Arguments args(info);
|
| + CallbackHolderBase* holder_base = NULL;
|
| + CHECK(args.GetData(&holder_base));
|
|
|
| - typedef CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| + typedef CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT;
|
| + HolderT* holder = static_cast<HolderT*>(holder_base);
|
|
|
| $if ARITY != 0 [[
|
|
|
|
|
| -$for ARG [[ typename RemoveConstRef<P$(ARG)>::Type a$(ARG);
|
| +$for ARG [[ typename RemoveConstRef<P$(ARG)>::Type a$(ARG);
|
|
|
| ]]
|
| - if (
|
| -$for ARG ||
|
| - [[!args.GetNext(&a$(ARG))]]) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| + if ($for ARG ||
|
| + [[!GetNextArgument(&args, holder->flags, $if ARG == 1 [[true]] $else [[false]], &a$(ARG))]]) {
|
| + args.ThrowError();
|
| + return;
|
| + }
|
|
|
| ]]
|
|
|
| - Invoker<R$for ARG [[, P$(ARG)]]>::Go(&args, holder->callback$for ARG [[, a$(ARG)]]);
|
| -}
|
| + Invoker<R$for ARG [[, P$(ARG)]]>::Go(&args, holder->callback$for ARG [[, a$(ARG)]]);
|
| + }
|
| +};
|
|
|
| ]]
|
|
|
| @@ -162,27 +195,22 @@ struct Converter<internal::CallbackHolderBase*>
|
| : public WrappableConverter<internal::CallbackHolderBase> {};
|
|
|
|
|
| -// Creates a v8::FunctionTemplate that will run the provided base::Callback each
|
| -// time it is called. JavaScript arguments and return values are converted via
|
| -// gin::Converter.
|
| -$range ARITY 0..MAX_ARITY
|
| -$for ARITY [[
|
| -$range ARG 1..ARITY
|
| -
|
| -template<typename R$for ARG [[, typename P$(ARG)]]>
|
| +// 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 gin::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<R($for ARG , [[P$(ARG)]])> callback) {
|
| - typedef internal::CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT;
|
| - scoped_refptr<HolderT> holder(new HolderT(callback));
|
| + const base::Callback<Sig> callback,
|
| + int flags = 0) {
|
| + typedef internal::CallbackHolder<Sig> HolderT;
|
| + scoped_refptr<HolderT> holder(new HolderT(callback, flags));
|
| return v8::FunctionTemplate::New(
|
| - isolate,
|
| - &internal::DispatchToCallback<R$for ARG [[, P$(ARG)]]>,
|
| + &internal::Dispatcher<Sig>::DispatchToCallback,
|
| ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
|
| }
|
|
|
| -]]
|
| -
|
| } // namespace gin
|
|
|
| #endif // GIN_FUNCTION_TEMPLATE_H_
|
|
|