Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Side by Side Diff: mojo/bindings/js/core.cc

Issue 214183003: Change mojo JS bindings to expose a handle object, which is Closed when garbage (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/bindings/js/core.h" 5 #include "mojo/bindings/js/core.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "gin/arguments.h" 9 #include "gin/arguments.h"
10 #include "gin/array_buffer.h" 10 #include "gin/array_buffer.h"
11 #include "gin/converter.h" 11 #include "gin/converter.h"
12 #include "gin/dictionary.h" 12 #include "gin/dictionary.h"
13 #include "gin/function_template.h" 13 #include "gin/function_template.h"
14 #include "gin/handle.h"
14 #include "gin/object_template_builder.h" 15 #include "gin/object_template_builder.h"
15 #include "gin/per_isolate_data.h" 16 #include "gin/per_isolate_data.h"
16 #include "gin/public/wrapper_info.h" 17 #include "gin/public/wrapper_info.h"
18 #include "gin/wrappable.h"
17 #include "mojo/bindings/js/handle.h" 19 #include "mojo/bindings/js/handle.h"
18 20
19 namespace mojo { 21 namespace mojo {
20 namespace js { 22 namespace js {
21 23
22 namespace { 24 namespace {
23 25
26 class HandleWrapper : public gin::Wrappable<HandleWrapper> {
27 public:
28 static gin::WrapperInfo kWrapperInfo;
29
30 static gin::Handle<HandleWrapper> Create(v8::Isolate* isolate,
31 MojoHandle handle) {
32 return CreateHandle(isolate, new HandleWrapper(handle));
33 }
34
35 MojoHandle get() const { return handle_.get().value(); }
36 void Close() { handle_.reset(); }
37
38 protected:
39 HandleWrapper(MojoHandle handle) : handle_(mojo::Handle(handle)) {}
40 virtual ~HandleWrapper() {}
41 ScopedHandle handle_;
42 };
43
44 gin::WrapperInfo HandleWrapper::kWrapperInfo = { gin::kEmbedderNativeGin };
45
46 MojoResult CloseHandle(gin::Handle<HandleWrapper> handle) {
47 handle->Close();
48 return MOJO_RESULT_OK;
49 }
50
51 MojoResult WaitHandle(gin::Handle<HandleWrapper> handle,
52 MojoWaitFlags flags,
53 MojoDeadline deadline) {
54 return MojoWait(handle->get(), flags, deadline);
55 }
56
57 MojoResult WaitMany(const std::vector<gin::Handle<HandleWrapper> >& handles,
58 const std::vector<MojoWaitFlags>& flags,
59 MojoDeadline deadline) {
60 std::vector<mojo::Handle> raw_handles;
61 for (size_t i = 0; i < handles.size(); ++i)
62 raw_handles[i].set_value(handles[i]->get());
63 return mojo::WaitMany(raw_handles, flags, deadline);
64 }
65
24 gin::Dictionary CreateMessagePipe(const gin::Arguments& args) { 66 gin::Dictionary CreateMessagePipe(const gin::Arguments& args) {
25 MojoHandle handle0 = MOJO_HANDLE_INVALID; 67 MojoHandle handle0 = MOJO_HANDLE_INVALID;
26 MojoHandle handle1 = MOJO_HANDLE_INVALID; 68 MojoHandle handle1 = MOJO_HANDLE_INVALID;
27 MojoResult result = MojoCreateMessagePipe(&handle0, &handle1); 69 MojoResult result = MojoCreateMessagePipe(&handle0, &handle1);
28 CHECK(result == MOJO_RESULT_OK); 70 CHECK(result == MOJO_RESULT_OK);
29 71
30 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 72 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
31 dictionary.Set("handle0", handle0); 73 dictionary.Set("handle0", HandleWrapper::Create(args.isolate(), handle0));
32 dictionary.Set("handle1", handle1); 74 dictionary.Set("handle1", HandleWrapper::Create(args.isolate(), handle1));
33 return dictionary; 75 return dictionary;
34 } 76 }
35 77
36 MojoResult WriteMessage(MojoHandle handle, 78 MojoResult WriteMessage(gin::Handle<HandleWrapper> handle,
37 const gin::ArrayBufferView& buffer, 79 const gin::ArrayBufferView& buffer,
38 const std::vector<MojoHandle>& handles, 80 const std::vector<gin::Handle<HandleWrapper> >& handles,
39 MojoWriteMessageFlags flags) { 81 MojoWriteMessageFlags flags) {
40 return MojoWriteMessage(handle, 82 std::vector<MojoHandle> raw_handles;
abarth-chromium 2014/03/29 01:56:17 Do you want to resize the vector to the final size
Matt Perry 2014/03/31 19:34:17 Done.
83 for (size_t i = 0; i < handles.size(); ++i)
84 raw_handles[i] = handles[i]->get();
85 return MojoWriteMessage(handle->get(),
41 buffer.bytes(), 86 buffer.bytes(),
42 static_cast<uint32_t>(buffer.num_bytes()), 87 static_cast<uint32_t>(buffer.num_bytes()),
43 handles.empty() ? NULL : &handles[0], 88 raw_handles.empty() ? NULL : &raw_handles[0],
44 static_cast<uint32_t>(handles.size()), 89 static_cast<uint32_t>(handles.size()),
45 flags); 90 flags);
46 } 91 }
47 92
48 gin::Dictionary ReadMessage(const gin::Arguments& args, 93 gin::Dictionary ReadMessage(const gin::Arguments& args,
49 MojoHandle handle, 94 gin::Handle<HandleWrapper> handle,
50 MojoReadMessageFlags flags) { 95 MojoReadMessageFlags flags) {
51 uint32_t num_bytes = 0; 96 uint32_t num_bytes = 0;
52 uint32_t num_handles = 0; 97 uint32_t num_handles = 0;
53 MojoResult result = MojoReadMessage( 98 MojoResult result = MojoReadMessage(
54 handle, NULL, &num_bytes, NULL, &num_handles, flags); 99 handle->get(), NULL, &num_bytes, NULL, &num_handles, flags);
55 if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) { 100 if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) {
56 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 101 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
57 dictionary.Set("result", result); 102 dictionary.Set("result", result);
58 return dictionary; 103 return dictionary;
59 } 104 }
60 105
61 v8::Handle<v8::ArrayBuffer> array_buffer = 106 v8::Handle<v8::ArrayBuffer> array_buffer =
62 v8::ArrayBuffer::New(args.isolate(), num_bytes); 107 v8::ArrayBuffer::New(args.isolate(), num_bytes);
63 std::vector<MojoHandle> handles(num_handles); 108 std::vector<MojoHandle> raw_handles(num_handles);
64 109
65 gin::ArrayBuffer buffer; 110 gin::ArrayBuffer buffer;
66 ConvertFromV8(args.isolate(), array_buffer, &buffer); 111 ConvertFromV8(args.isolate(), array_buffer, &buffer);
67 CHECK(buffer.num_bytes() == num_bytes); 112 CHECK(buffer.num_bytes() == num_bytes);
68 113
69 result = MojoReadMessage(handle, 114 result = MojoReadMessage(handle->get(),
70 buffer.bytes(), 115 buffer.bytes(),
71 &num_bytes, 116 &num_bytes,
72 handles.empty() ? NULL : &handles[0], 117 raw_handles.empty() ? NULL : &raw_handles[0],
73 &num_handles, 118 &num_handles,
74 flags); 119 flags);
75 120
76 CHECK(buffer.num_bytes() == num_bytes); 121 CHECK(buffer.num_bytes() == num_bytes);
77 CHECK(handles.size() == num_handles); 122 CHECK(raw_handles.size() == num_handles);
78 123
79 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 124 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
80 dictionary.Set("result", result); 125 dictionary.Set("result", result);
81 dictionary.Set("buffer", array_buffer); 126 dictionary.Set("buffer", array_buffer);
127
128 std::vector<gin::Handle<HandleWrapper> > handles;
abarth-chromium 2014/03/29 01:56:17 Ditto.
Matt Perry 2014/03/31 19:34:17 Done.
129 for (size_t i = 0; i < raw_handles.size(); ++i)
130 handles[i] = HandleWrapper::Create(args.isolate(), raw_handles[i]);
82 dictionary.Set("handles", handles); 131 dictionary.Set("handles", handles);
83 return dictionary; 132 return dictionary;
84 } 133 }
85 134
86 gin::Dictionary CreateDataPipe(const gin::Arguments& args, 135 gin::Dictionary CreateDataPipe(const gin::Arguments& args,
87 v8::Handle<v8::Value> options_value) { 136 v8::Handle<v8::Value> options_value) {
88 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 137 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
89 dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT); 138 dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
90 139
91 MojoHandle producer_handle = MOJO_HANDLE_INVALID; 140 MojoHandle producer_handle = MOJO_HANDLE_INVALID;
(...skipping 17 matching lines...) Expand all
109 result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle); 158 result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle);
110 } else if (options_value->IsNull() || options_value->IsUndefined()) { 159 } else if (options_value->IsNull() || options_value->IsUndefined()) {
111 result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle); 160 result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle);
112 } else { 161 } else {
113 return dictionary; 162 return dictionary;
114 } 163 }
115 164
116 CHECK_EQ(MOJO_RESULT_OK, result); 165 CHECK_EQ(MOJO_RESULT_OK, result);
117 166
118 dictionary.Set("result", result); 167 dictionary.Set("result", result);
119 dictionary.Set("producerHandle", producer_handle); 168 dictionary.Set("producerHandle",
120 dictionary.Set("consumerHandle", consumer_handle); 169 HandleWrapper::Create(args.isolate(), producer_handle));
170 dictionary.Set("consumerHandle",
171 HandleWrapper::Create(args.isolate(), consumer_handle));
121 return dictionary; 172 return dictionary;
122 } 173 }
123 174
124 gin::Dictionary WriteData(const gin::Arguments& args, 175 gin::Dictionary WriteData(const gin::Arguments& args,
125 MojoHandle handle, 176 gin::Handle<HandleWrapper> handle,
126 const gin::ArrayBufferView& buffer, 177 const gin::ArrayBufferView& buffer,
127 MojoWriteDataFlags flags) { 178 MojoWriteDataFlags flags) {
128 uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes()); 179 uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes());
129 MojoResult result = MojoWriteData(handle, buffer.bytes(), &num_bytes, flags); 180 MojoResult result =
181 MojoWriteData(handle->get(), buffer.bytes(), &num_bytes, flags);
130 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 182 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
131 dictionary.Set("result", result); 183 dictionary.Set("result", result);
132 dictionary.Set("numBytes", num_bytes); 184 dictionary.Set("numBytes", num_bytes);
133 return dictionary; 185 return dictionary;
134 } 186 }
135 187
136 gin::Dictionary ReadData(const gin::Arguments& args, 188 gin::Dictionary ReadData(const gin::Arguments& args,
137 MojoHandle handle, 189 gin::Handle<HandleWrapper> handle,
138 MojoReadDataFlags flags) { 190 MojoReadDataFlags flags) {
139 uint32_t num_bytes = 0; 191 uint32_t num_bytes = 0;
140 MojoResult result = MojoReadData( 192 MojoResult result = MojoReadData(
141 handle, NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY); 193 handle->get(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
142 if (result != MOJO_RESULT_OK) { 194 if (result != MOJO_RESULT_OK) {
143 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 195 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
144 dictionary.Set("result", result); 196 dictionary.Set("result", result);
145 return dictionary; 197 return dictionary;
146 } 198 }
147 199
148 v8::Handle<v8::ArrayBuffer> array_buffer = 200 v8::Handle<v8::ArrayBuffer> array_buffer =
149 v8::ArrayBuffer::New(args.isolate(), num_bytes); 201 v8::ArrayBuffer::New(args.isolate(), num_bytes);
150 gin::ArrayBuffer buffer; 202 gin::ArrayBuffer buffer;
151 ConvertFromV8(args.isolate(), array_buffer, &buffer); 203 ConvertFromV8(args.isolate(), array_buffer, &buffer);
152 CHECK_EQ(num_bytes, buffer.num_bytes()); 204 CHECK_EQ(num_bytes, buffer.num_bytes());
153 205
154 result = MojoReadData(handle, buffer.bytes(), &num_bytes, flags); 206 result = MojoReadData(handle->get(), buffer.bytes(), &num_bytes, flags);
155 CHECK_EQ(num_bytes, buffer.num_bytes()); 207 CHECK_EQ(num_bytes, buffer.num_bytes());
156 208
157 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); 209 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
158 dictionary.Set("result", result); 210 dictionary.Set("result", result);
159 dictionary.Set("buffer", array_buffer); 211 dictionary.Set("buffer", array_buffer);
160 return dictionary; 212 return dictionary;
161 } 213 }
162 214
163 gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; 215 gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
164 216
165 } // namespace 217 } // namespace
166 218
167 const char Core::kModuleName[] = "mojo/bindings/js/core"; 219 const char Core::kModuleName[] = "mojo/bindings/js/core";
168 220
169 v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) { 221 v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
170 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); 222 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
171 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( 223 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
172 &g_wrapper_info); 224 &g_wrapper_info);
173 225
174 if (templ.IsEmpty()) { 226 if (templ.IsEmpty()) {
175 templ = gin::ObjectTemplateBuilder(isolate) 227 templ = gin::ObjectTemplateBuilder(isolate)
176 .SetMethod("close", mojo::CloseRaw) 228 // TODO(mpcomplete): Should these just be methods on the JS Handle
177 .SetMethod("wait", mojo::Wait) 229 // object?
abarth-chromium 2014/03/29 01:56:17 Yeah, at some point we should probably make these
178 .SetMethod("waitMany", mojo::WaitMany<std::vector<mojo::Handle>, 230 .SetMethod("close", CloseHandle)
179 std::vector<MojoWaitFlags> >) 231 .SetMethod("wait", WaitHandle)
232 .SetMethod("waitMany", WaitMany)
180 .SetMethod("createMessagePipe", CreateMessagePipe) 233 .SetMethod("createMessagePipe", CreateMessagePipe)
181 .SetMethod("writeMessage", WriteMessage) 234 .SetMethod("writeMessage", WriteMessage)
182 .SetMethod("readMessage", ReadMessage) 235 .SetMethod("readMessage", ReadMessage)
183 .SetMethod("createDataPipe", CreateDataPipe) 236 .SetMethod("createDataPipe", CreateDataPipe)
184 .SetMethod("writeData", WriteData) 237 .SetMethod("writeData", WriteData)
185 .SetMethod("readData", ReadData) 238 .SetMethod("readData", ReadData)
186 239
187 // TODO(vtl): Change name of "kInvalidHandle", now that there's no such 240 // TODO(vtl): Change name of "kInvalidHandle", now that there's no such
188 // C++ constant? 241 // C++ constant?
189 .SetValue("kInvalidHandle", mojo::Handle()) 242 .SetValue("kInvalidHandle", mojo::Handle())
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 .Build(); 290 .Build();
238 291
239 data->SetObjectTemplate(&g_wrapper_info, templ); 292 data->SetObjectTemplate(&g_wrapper_info, templ);
240 } 293 }
241 294
242 return templ->NewInstance(); 295 return templ->NewInstance();
243 } 296 }
244 297
245 } // namespace js 298 } // namespace js
246 } // namespace mojo 299 } // namespace mojo
OLDNEW
« gin/test/gtest.cc ('K') | « gin/test/gtest.cc ('k') | mojo/bindings/js/core_unittests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698