Commit b520e13a authored by aa@chromium.org's avatar aa@chromium.org

Implement gin::ObjectTemplateBuilder

BUG=

Review URL: https://codereview.chromium.org/93813002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237867 0039d316-1c4b-4281-b951-d872f2087c98
parent d4d1e4b1
......@@ -91,12 +91,15 @@ bool Converter<double>::FromV8(Isolate* isolate, Handle<Value> val,
return true;
}
Handle<Value> Converter<base::StringPiece>::ToV8(
Isolate* isolate, const base::StringPiece& val) {
return String::NewFromUtf8(isolate, val.data(), String::kNormalString,
static_cast<uint32_t>(val.length()));
}
Handle<Value> Converter<std::string>::ToV8(Isolate* isolate,
const std::string& val) {
return String::NewFromUtf8(isolate,
val.data(),
String::kNormalString,
static_cast<uint32_t>(val.length()));
return Converter<base::StringPiece>::ToV8(isolate, val);
}
bool Converter<std::string>::FromV8(Isolate* isolate, Handle<Value> val,
......@@ -171,7 +174,7 @@ bool Converter<Handle<Value> >::FromV8(Isolate* isolate, Handle<Value> val,
}
v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
const std::string& val) {
const base::StringPiece& val) {
return String::NewFromUtf8(isolate,
val.data(),
String::kInternalizedString,
......
......@@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include "base/strings/string_piece.h"
#include "v8/include/v8.h"
namespace gin {
......@@ -71,6 +72,13 @@ struct Converter<double> {
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,
......@@ -164,12 +172,12 @@ v8::Handle<v8::Value> ConvertToV8(v8::Isolate* isolate,
}
inline v8::Handle<v8::String> StringToV8(v8::Isolate* isolate,
std::string input) {
const base::StringPiece& input) {
return ConvertToV8(isolate, input).As<v8::String>();
}
v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate,
const std::string& val);
const base::StringPiece& val);
template<typename T>
bool ConvertFromV8(v8::Isolate* isolate, v8::Handle<v8::Value> input,
......
......@@ -4,6 +4,9 @@
#ifndef GIN_FUNCTION_TEMPLATE_H_
#define GIN_FUNCTION_TEMPLATE_H_
// 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 file.
......@@ -354,3 +357,5 @@ v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
}
} // namespace gin
#endif // GIN_FUNCTION_TEMPLATE_H_
......@@ -5,6 +5,9 @@ $$
$$ http://code.google.com/p/googletest/wiki/PumpManual
$$
#ifndef GIN_FUNCTION_TEMPLATE_H_
#define GIN_FUNCTION_TEMPLATE_H_
$var MAX_ARITY = 4
// Copyright 2013 The Chromium Authors. All rights reserved.
......@@ -181,3 +184,5 @@ v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
]]
} // namespace gin
#endif // GIN_FUNCTION_TEMPLATE_H_
......@@ -40,6 +40,8 @@
'modules/module_registry.h',
'modules/module_runner_delegate.cc',
'modules/module_runner_delegate.h',
'object_template_builder.cc',
'object_template_builder.h',
'per_context_data.cc',
'per_context_data.h',
'per_isolate_data.cc',
......
// 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 file.
#include "gin/object_template_builder.h"
namespace gin {
ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
: isolate_(isolate), template_(v8::ObjectTemplate::New(isolate)) {
}
ObjectTemplateBuilder::~ObjectTemplateBuilder() {
}
ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(
const base::StringPiece& name, v8::Handle<v8::Data> val) {
template_->Set(StringToSymbol(isolate_, name), val);
return *this;
}
v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
v8::Local<v8::ObjectTemplate> result = template_;
template_.Clear();
return result;
}
} // namespace gin
// 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 file.
#ifndef GIN_OBJECT_TEMPLATE_BUILDER_H_
#define GIN_OBJECT_TEMPLATE_BUILDER_H_
#include "base/bind.h"
#include "base/strings/string_piece.h"
#include "gin/converter.h"
#include "gin/function_template.h"
#include "v8/include/v8.h"
namespace gin {
// 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));
}
template<typename T>
ObjectTemplateBuilder& SetMethod(const base::StringPiece& name, T val) {
return SetMethod(name, base::Bind(val));
}
template<typename T>
ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
const base::Callback<T>& callback) {
return SetImpl(name, CreateFunctionTemplate(isolate_, callback));
}
v8::Local<v8::ObjectTemplate> Build();
private:
ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
v8::Handle<v8::Data> val);
v8::Isolate* isolate_;
// ObjectTemplateBuilder should only be used on the stack.
v8::Local<v8::ObjectTemplate> template_;
};
} // namespace gin
#endif // GIN_OBJECT_TEMPLATE_BUILDER_H_
......@@ -9,6 +9,7 @@
#include "gin/arguments.h"
#include "gin/converter.h"
#include "gin/function_template.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
#include "gin/wrappable.h"
......@@ -18,13 +19,7 @@ namespace gin {
namespace {
void Fail(const v8::FunctionCallbackInfo<v8::Value>& info) {
Arguments args(info);
std::string description;
if (!args.GetNext(&description))
return args.ThrowError();
void Fail(const std::string& description) {
FAIL() << description;
}
......@@ -53,15 +48,12 @@ v8::Local<v8::ObjectTemplate> GTest::GetTemplate(v8::Isolate* isolate) {
v8::Local<v8::ObjectTemplate> templ =
data->GetObjectTemplate(&g_wrapper_info);
if (templ.IsEmpty()) {
templ = v8::ObjectTemplate::New();
templ->Set(StringToSymbol(isolate, "fail"),
v8::FunctionTemplate::New(Fail));
templ->Set(StringToSymbol(isolate, "expectTrue"),
CreateFunctionTemplate(isolate, base::Bind(ExpectTrue)));
templ->Set(StringToSymbol(isolate, "expectFalse"),
CreateFunctionTemplate(isolate, base::Bind(ExpectFalse)));
templ->Set(StringToSymbol(isolate, "expectEqual"),
CreateFunctionTemplate(isolate, base::Bind(ExpectEqual)));
templ = ObjectTemplateBuilder(isolate)
.SetMethod("fail", Fail)
.SetMethod("expectTrue", ExpectTrue)
.SetMethod("expectFalse", ExpectFalse)
.SetMethod("expectEqual", ExpectEqual)
.Build();
data->SetObjectTemplate(&g_wrapper_info, templ);
}
return templ;
......
......@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "gin/function_template.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "mojo/public/bindings/js/handle.h"
......@@ -31,9 +32,10 @@ v8::Local<v8::ObjectTemplate> Threading::GetTemplate(v8::Isolate* isolate) {
&g_wrapper_info);
if (templ.IsEmpty()) {
templ = v8::ObjectTemplate::New();
templ->Set(gin::StringToSymbol(isolate, "quit"),
gin::CreateFunctionTemplate(isolate, base::Bind(Quit)));
templ = gin::ObjectTemplateBuilder(isolate)
.SetMethod("quit", Quit)
.Build();
data->SetObjectTemplate(&g_wrapper_info, templ);
}
......
......@@ -11,6 +11,7 @@
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "gin/function_template.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
#include "mojo/public/bindings/js/handle.h"
......@@ -93,85 +94,49 @@ v8::Local<v8::ObjectTemplate> Core::GetTemplate(v8::Isolate* isolate) {
&g_wrapper_info);
if (templ.IsEmpty()) {
templ = v8::ObjectTemplate::New(isolate);
templ->Set(gin::StringToSymbol(isolate, "close"),
gin::CreateFunctionTemplate(isolate,
base::Bind(mojo::CloseRaw)));
templ->Set(gin::StringToSymbol(isolate, "wait"),
gin::CreateFunctionTemplate(isolate,
base::Bind(mojo::Wait)));
templ->Set(gin::StringToSymbol(isolate, "waitMany"),
gin::CreateFunctionTemplate(isolate,
base::Bind(mojo::WaitMany<std::vector<mojo::Handle>,
std::vector<MojoWaitFlags> >)));
templ->Set(gin::StringToSymbol(isolate, "createMessagePipe"),
gin::CreateFunctionTemplate(isolate,
base::Bind(CreateMessagePipe)));
templ->Set(gin::StringToSymbol(isolate, "writeMessage"),
gin::CreateFunctionTemplate(isolate,
base::Bind(WriteMessage)));
templ->Set(gin::StringToSymbol(isolate, "readMessage"),
gin::CreateFunctionTemplate(isolate,
base::Bind(ReadMessage)));
// TODO(vtl): Change name of "kInvalidHandle", now that there's no such C++
// constant?
templ->Set(gin::StringToSymbol(isolate, "kInvalidHandle"),
gin::ConvertToV8(isolate, mojo::Handle()));
templ->Set(gin::StringToSymbol(isolate, "RESULT_OK"),
gin::ConvertToV8(isolate, MOJO_RESULT_OK));
templ->Set(gin::StringToSymbol(isolate, "RESULT_CANCELLED"),
gin::ConvertToV8(isolate, MOJO_RESULT_CANCELLED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_UNKNOWN"),
gin::ConvertToV8(isolate, MOJO_RESULT_UNKNOWN));
templ->Set(gin::StringToSymbol(isolate, "RESULT_INVALID_ARGUMENT"),
gin::ConvertToV8(isolate, MOJO_RESULT_INVALID_ARGUMENT));
templ->Set(gin::StringToSymbol(isolate, "RESULT_DEADLINE_EXCEEDED"),
gin::ConvertToV8(isolate, MOJO_RESULT_DEADLINE_EXCEEDED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_NOT_FOUND"),
gin::ConvertToV8(isolate, MOJO_RESULT_NOT_FOUND));
templ->Set(gin::StringToSymbol(isolate, "RESULT_ALREADY_EXISTS"),
gin::ConvertToV8(isolate, MOJO_RESULT_ALREADY_EXISTS));
templ->Set(gin::StringToSymbol(isolate, "RESULT_PERMISSION_DENIED"),
gin::ConvertToV8(isolate, MOJO_RESULT_PERMISSION_DENIED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_RESOURCE_EXHAUSTED"),
gin::ConvertToV8(isolate, MOJO_RESULT_RESOURCE_EXHAUSTED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_FAILED_PRECONDITION"),
gin::ConvertToV8(isolate, MOJO_RESULT_FAILED_PRECONDITION));
templ->Set(gin::StringToSymbol(isolate, "RESULT_ABORTED"),
gin::ConvertToV8(isolate, MOJO_RESULT_ABORTED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_OUT_OF_RANGE"),
gin::ConvertToV8(isolate, MOJO_RESULT_OUT_OF_RANGE));
templ->Set(gin::StringToSymbol(isolate, "RESULT_UNIMPLEMENTED"),
gin::ConvertToV8(isolate, MOJO_RESULT_UNIMPLEMENTED));
templ->Set(gin::StringToSymbol(isolate, "RESULT_INTERNAL"),
gin::ConvertToV8(isolate, MOJO_RESULT_INTERNAL));
templ->Set(gin::StringToSymbol(isolate, "RESULT_UNAVAILABLE"),
gin::ConvertToV8(isolate, MOJO_RESULT_UNAVAILABLE));
templ->Set(gin::StringToSymbol(isolate, "RESULT_DATA_LOSS"),
gin::ConvertToV8(isolate, MOJO_RESULT_DATA_LOSS));
templ->Set(gin::StringToSymbol(isolate, "DEADLINE_INDEFINITE"),
gin::ConvertToV8(isolate, MOJO_DEADLINE_INDEFINITE));
templ->Set(gin::StringToSymbol(isolate, "WAIT_FLAG_NONE"),
gin::ConvertToV8(isolate, MOJO_WAIT_FLAG_NONE));
templ->Set(gin::StringToSymbol(isolate, "WAIT_FLAG_READABLE"),
gin::ConvertToV8(isolate, MOJO_WAIT_FLAG_READABLE));
templ->Set(gin::StringToSymbol(isolate, "WAIT_FLAG_READABLE"),
gin::ConvertToV8(isolate, MOJO_WAIT_FLAG_READABLE));
templ->Set(gin::StringToSymbol(isolate, "WAIT_FLAG_EVERYTHING"),
gin::ConvertToV8(isolate, MOJO_WAIT_FLAG_EVERYTHING));
templ->Set(gin::StringToSymbol(isolate, "WRITE_MESSAGE_FLAG_NONE"),
gin::ConvertToV8(isolate, MOJO_WRITE_MESSAGE_FLAG_NONE));
templ->Set(gin::StringToSymbol(isolate, "READ_MESSAGE_FLAG_NONE"),
gin::ConvertToV8(isolate, MOJO_READ_MESSAGE_FLAG_NONE));
templ->Set(gin::StringToSymbol(isolate, "READ_MESSAGE_FLAG_MAY_DISCARD"),
gin::ConvertToV8(isolate, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
templ = gin::ObjectTemplateBuilder(isolate)
.SetMethod("close", mojo::CloseRaw)
.SetMethod("wait", mojo::Wait)
.SetMethod("waitMany", mojo::WaitMany<std::vector<mojo::Handle>,
std::vector<MojoWaitFlags> >)
.SetMethod("createMessagePipe", CreateMessagePipe)
.SetMethod("writeMessage", WriteMessage)
.SetMethod("readMessage", ReadMessage)
// TODO(vtl): Change name of "kInvalidHandle", now that there's no such
// C++ constant?
.SetValue("kInvalidHandle", mojo::Handle())
.SetValue("RESULT_OK", MOJO_RESULT_OK)
.SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
.SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
.SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
.SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
.SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
.SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
.SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
.SetValue("RESULT_RESOURCE_EXHAUSTED", MOJO_RESULT_RESOURCE_EXHAUSTED)
.SetValue("RESULT_FAILED_PRECONDITION", MOJO_RESULT_FAILED_PRECONDITION)
.SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
.SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
.SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
.SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
.SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
.SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
.SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
.SetValue("WAIT_FLAG_NONE", MOJO_WAIT_FLAG_NONE)
.SetValue("WAIT_FLAG_READABLE", MOJO_WAIT_FLAG_READABLE)
.SetValue("WAIT_FLAG_READABLE", MOJO_WAIT_FLAG_READABLE)
.SetValue("WAIT_FLAG_EVERYTHING", MOJO_WAIT_FLAG_EVERYTHING)
.SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
.SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
.SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
.Build();
data->SetObjectTemplate(&g_wrapper_info, templ);
}
......
......@@ -8,6 +8,7 @@
#include "gin/arguments.h"
#include "gin/converter.h"
#include "gin/function_template.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
#include "gin/wrappable.h"
......@@ -20,18 +21,9 @@ namespace js {
namespace {
void AsyncWait(const v8::FunctionCallbackInfo<v8::Value>& info) {
gin::Arguments args(info);
mojo::Handle handle;
MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE;
v8::Handle<v8::Function> callback;
if (!args.GetNext(&handle) ||
!args.GetNext(&flags) ||
!args.GetNext(&callback))
return args.ThrowError();
WaitingCallback* AsyncWait(const gin::Arguments& args, mojo::Handle handle,
MojoWaitFlags flags,
v8::Handle<v8::Function> callback) {
scoped_refptr<WaitingCallback> waiting_callback =
WaitingCallback::Create(args.isolate(), callback);
......@@ -40,7 +32,7 @@ void AsyncWait(const v8::FunctionCallbackInfo<v8::Value>& info) {
waiting_callback->set_wait_id(wait_id);
args.Return(waiting_callback.get());
return waiting_callback.get();
}
void CancelWait(WaitingCallback* waiting_callback) {
......@@ -64,12 +56,10 @@ v8::Local<v8::ObjectTemplate> Support::GetTemplate(v8::Isolate* isolate) {
if (templ.IsEmpty()) {
WaitingCallback::EnsureRegistered(isolate);
templ = v8::ObjectTemplate::New(isolate);
templ->Set(gin::StringToSymbol(isolate, "asyncWait"),
v8::FunctionTemplate::New(isolate, AsyncWait));
templ->Set(gin::StringToSymbol(isolate, "cancelWait"),
gin::CreateFunctionTemplate(isolate, base::Bind(CancelWait)));
templ = gin::ObjectTemplateBuilder(isolate)
.SetMethod("asyncWait", AsyncWait)
.SetMethod("cancelWait", CancelWait)
.Build();
data->SetObjectTemplate(&g_wrapper_info, templ);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment