OLD | NEW |
---|---|
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 MojoResult CloseHandle(gin::Handle<gin::HandleWrapper> handle) { | |
27 if (!handle->get().is_valid()) | |
28 return MOJO_RESULT_INVALID_ARGUMENT; | |
29 handle->Close(); | |
30 return MOJO_RESULT_OK; | |
31 } | |
32 | |
33 MojoResult WaitHandle(mojo::Handle handle, | |
34 MojoWaitFlags flags, | |
35 MojoDeadline deadline) { | |
36 return MojoWait(handle.value(), flags, deadline); | |
37 } | |
38 | |
39 MojoResult WaitMany( | |
40 const std::vector<mojo::Handle>& handles, | |
41 const std::vector<MojoWaitFlags>& flags, | |
42 MojoDeadline deadline) { | |
43 return mojo::WaitMany(handles, flags, deadline); | |
44 } | |
45 | |
24 gin::Dictionary CreateMessagePipe(const gin::Arguments& args) { | 46 gin::Dictionary CreateMessagePipe(const gin::Arguments& args) { |
25 MojoHandle handle0 = MOJO_HANDLE_INVALID; | 47 MojoHandle handle0 = MOJO_HANDLE_INVALID; |
26 MojoHandle handle1 = MOJO_HANDLE_INVALID; | 48 MojoHandle handle1 = MOJO_HANDLE_INVALID; |
27 MojoResult result = MojoCreateMessagePipe(&handle0, &handle1); | 49 MojoResult result = MojoCreateMessagePipe(&handle0, &handle1); |
28 CHECK(result == MOJO_RESULT_OK); | 50 CHECK(result == MOJO_RESULT_OK); |
29 | 51 |
30 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 52 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
31 dictionary.Set("handle0", handle0); | 53 dictionary.Set("handle0", mojo::Handle(handle0)); |
32 dictionary.Set("handle1", handle1); | 54 dictionary.Set("handle1", mojo::Handle(handle1)); |
33 return dictionary; | 55 return dictionary; |
34 } | 56 } |
35 | 57 |
36 MojoResult WriteMessage(MojoHandle handle, | 58 MojoResult WriteMessage( |
37 const gin::ArrayBufferView& buffer, | 59 mojo::Handle handle, |
38 const std::vector<MojoHandle>& handles, | 60 const gin::ArrayBufferView& buffer, |
39 MojoWriteMessageFlags flags) { | 61 const std::vector<gin::Handle<gin::HandleWrapper> >& handles, |
40 return MojoWriteMessage(handle, | 62 MojoWriteMessageFlags flags) { |
63 std::vector<MojoHandle> raw_handles(handles.size()); | |
64 for (size_t i = 0; i < handles.size(); ++i) | |
65 raw_handles[i] = handles[i]->get().value(); | |
66 MojoResult rv = MojoWriteMessage(handle.value(), | |
41 buffer.bytes(), | 67 buffer.bytes(), |
42 static_cast<uint32_t>(buffer.num_bytes()), | 68 static_cast<uint32_t>(buffer.num_bytes()), |
43 handles.empty() ? NULL : &handles[0], | 69 raw_handles.empty() ? NULL : &raw_handles[0], |
44 static_cast<uint32_t>(handles.size()), | 70 static_cast<uint32_t>(raw_handles.size()), |
45 flags); | 71 flags); |
72 // MojoWriteMessage takes ownership of the handles upon success, so | |
73 // release them here. | |
74 if (rv == MOJO_RESULT_OK) { | |
75 for (size_t i = 0; i < handles.size(); ++i) | |
76 mojo::Handle _ MOJO_ALLOW_UNUSED = handles[i]->release(); | |
Nico
2014/05/05 16:01:44
It's better to write this `ignore_result(handles[i
| |
77 } | |
abarth-chromium
2014/04/02 22:57:56
Is there a better idiom for this in C++? For exam
Matt Perry
2014/04/02 23:01:26
There's no C++ version that does this for us AFAIC
| |
78 return rv; | |
46 } | 79 } |
47 | 80 |
48 gin::Dictionary ReadMessage(const gin::Arguments& args, | 81 gin::Dictionary ReadMessage(const gin::Arguments& args, |
49 MojoHandle handle, | 82 mojo::Handle handle, |
50 MojoReadMessageFlags flags) { | 83 MojoReadMessageFlags flags) { |
51 uint32_t num_bytes = 0; | 84 uint32_t num_bytes = 0; |
52 uint32_t num_handles = 0; | 85 uint32_t num_handles = 0; |
53 MojoResult result = MojoReadMessage( | 86 MojoResult result = MojoReadMessage( |
54 handle, NULL, &num_bytes, NULL, &num_handles, flags); | 87 handle.value(), NULL, &num_bytes, NULL, &num_handles, flags); |
55 if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) { | 88 if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) { |
56 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 89 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
57 dictionary.Set("result", result); | 90 dictionary.Set("result", result); |
58 return dictionary; | 91 return dictionary; |
59 } | 92 } |
60 | 93 |
61 v8::Handle<v8::ArrayBuffer> array_buffer = | 94 v8::Handle<v8::ArrayBuffer> array_buffer = |
62 v8::ArrayBuffer::New(args.isolate(), num_bytes); | 95 v8::ArrayBuffer::New(args.isolate(), num_bytes); |
63 std::vector<MojoHandle> handles(num_handles); | 96 std::vector<mojo::Handle> handles(num_handles); |
64 | 97 |
65 gin::ArrayBuffer buffer; | 98 gin::ArrayBuffer buffer; |
66 ConvertFromV8(args.isolate(), array_buffer, &buffer); | 99 ConvertFromV8(args.isolate(), array_buffer, &buffer); |
67 CHECK(buffer.num_bytes() == num_bytes); | 100 CHECK(buffer.num_bytes() == num_bytes); |
68 | 101 |
69 result = MojoReadMessage(handle, | 102 result = MojoReadMessage(handle.value(), |
70 buffer.bytes(), | 103 buffer.bytes(), |
71 &num_bytes, | 104 &num_bytes, |
72 handles.empty() ? NULL : &handles[0], | 105 handles.empty() ? NULL : |
106 reinterpret_cast<MojoHandle*>(&handles[0]), | |
73 &num_handles, | 107 &num_handles, |
74 flags); | 108 flags); |
75 | 109 |
76 CHECK(buffer.num_bytes() == num_bytes); | 110 CHECK(buffer.num_bytes() == num_bytes); |
77 CHECK(handles.size() == num_handles); | 111 CHECK(handles.size() == num_handles); |
78 | 112 |
79 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 113 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
80 dictionary.Set("result", result); | 114 dictionary.Set("result", result); |
81 dictionary.Set("buffer", array_buffer); | 115 dictionary.Set("buffer", array_buffer); |
82 dictionary.Set("handles", handles); | 116 dictionary.Set("handles", handles); |
(...skipping 26 matching lines...) Expand all Loading... | |
109 result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle); | 143 result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle); |
110 } else if (options_value->IsNull() || options_value->IsUndefined()) { | 144 } else if (options_value->IsNull() || options_value->IsUndefined()) { |
111 result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle); | 145 result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle); |
112 } else { | 146 } else { |
113 return dictionary; | 147 return dictionary; |
114 } | 148 } |
115 | 149 |
116 CHECK_EQ(MOJO_RESULT_OK, result); | 150 CHECK_EQ(MOJO_RESULT_OK, result); |
117 | 151 |
118 dictionary.Set("result", result); | 152 dictionary.Set("result", result); |
119 dictionary.Set("producerHandle", producer_handle); | 153 dictionary.Set("producerHandle", mojo::Handle(producer_handle)); |
120 dictionary.Set("consumerHandle", consumer_handle); | 154 dictionary.Set("consumerHandle", mojo::Handle(consumer_handle)); |
121 return dictionary; | 155 return dictionary; |
122 } | 156 } |
123 | 157 |
124 gin::Dictionary WriteData(const gin::Arguments& args, | 158 gin::Dictionary WriteData(const gin::Arguments& args, |
125 MojoHandle handle, | 159 mojo::Handle handle, |
126 const gin::ArrayBufferView& buffer, | 160 const gin::ArrayBufferView& buffer, |
127 MojoWriteDataFlags flags) { | 161 MojoWriteDataFlags flags) { |
128 uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes()); | 162 uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes()); |
129 MojoResult result = MojoWriteData(handle, buffer.bytes(), &num_bytes, flags); | 163 MojoResult result = |
164 MojoWriteData(handle.value(), buffer.bytes(), &num_bytes, flags); | |
130 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 165 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
131 dictionary.Set("result", result); | 166 dictionary.Set("result", result); |
132 dictionary.Set("numBytes", num_bytes); | 167 dictionary.Set("numBytes", num_bytes); |
133 return dictionary; | 168 return dictionary; |
134 } | 169 } |
135 | 170 |
136 gin::Dictionary ReadData(const gin::Arguments& args, | 171 gin::Dictionary ReadData(const gin::Arguments& args, |
137 MojoHandle handle, | 172 mojo::Handle handle, |
138 MojoReadDataFlags flags) { | 173 MojoReadDataFlags flags) { |
139 uint32_t num_bytes = 0; | 174 uint32_t num_bytes = 0; |
140 MojoResult result = MojoReadData( | 175 MojoResult result = MojoReadData( |
141 handle, NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY); | 176 handle.value(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY); |
142 if (result != MOJO_RESULT_OK) { | 177 if (result != MOJO_RESULT_OK) { |
143 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 178 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
144 dictionary.Set("result", result); | 179 dictionary.Set("result", result); |
145 return dictionary; | 180 return dictionary; |
146 } | 181 } |
147 | 182 |
148 v8::Handle<v8::ArrayBuffer> array_buffer = | 183 v8::Handle<v8::ArrayBuffer> array_buffer = |
149 v8::ArrayBuffer::New(args.isolate(), num_bytes); | 184 v8::ArrayBuffer::New(args.isolate(), num_bytes); |
150 gin::ArrayBuffer buffer; | 185 gin::ArrayBuffer buffer; |
151 ConvertFromV8(args.isolate(), array_buffer, &buffer); | 186 ConvertFromV8(args.isolate(), array_buffer, &buffer); |
152 CHECK_EQ(num_bytes, buffer.num_bytes()); | 187 CHECK_EQ(num_bytes, buffer.num_bytes()); |
153 | 188 |
154 result = MojoReadData(handle, buffer.bytes(), &num_bytes, flags); | 189 result = MojoReadData(handle.value(), buffer.bytes(), &num_bytes, flags); |
155 CHECK_EQ(num_bytes, buffer.num_bytes()); | 190 CHECK_EQ(num_bytes, buffer.num_bytes()); |
156 | 191 |
157 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); | 192 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); |
158 dictionary.Set("result", result); | 193 dictionary.Set("result", result); |
159 dictionary.Set("buffer", array_buffer); | 194 dictionary.Set("buffer", array_buffer); |
160 return dictionary; | 195 return dictionary; |
161 } | 196 } |
162 | 197 |
163 gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; | 198 gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; |
164 | 199 |
165 } // namespace | 200 } // namespace |
166 | 201 |
167 const char Core::kModuleName[] = "mojo/bindings/js/core"; | 202 const char Core::kModuleName[] = "mojo/bindings/js/core"; |
168 | 203 |
169 v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) { | 204 v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) { |
170 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); | 205 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); |
171 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( | 206 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( |
172 &g_wrapper_info); | 207 &g_wrapper_info); |
173 | 208 |
174 if (templ.IsEmpty()) { | 209 if (templ.IsEmpty()) { |
175 templ = gin::ObjectTemplateBuilder(isolate) | 210 templ = gin::ObjectTemplateBuilder(isolate) |
176 .SetMethod("close", mojo::CloseRaw) | 211 // TODO(mpcomplete): Should these just be methods on the JS Handle |
177 .SetMethod("wait", mojo::Wait) | 212 // object? |
178 .SetMethod("waitMany", mojo::WaitMany<std::vector<mojo::Handle>, | 213 .SetMethod("close", CloseHandle) |
179 std::vector<MojoWaitFlags> >) | 214 .SetMethod("wait", WaitHandle) |
215 .SetMethod("waitMany", WaitMany) | |
180 .SetMethod("createMessagePipe", CreateMessagePipe) | 216 .SetMethod("createMessagePipe", CreateMessagePipe) |
181 .SetMethod("writeMessage", WriteMessage) | 217 .SetMethod("writeMessage", WriteMessage) |
182 .SetMethod("readMessage", ReadMessage) | 218 .SetMethod("readMessage", ReadMessage) |
183 .SetMethod("createDataPipe", CreateDataPipe) | 219 .SetMethod("createDataPipe", CreateDataPipe) |
184 .SetMethod("writeData", WriteData) | 220 .SetMethod("writeData", WriteData) |
185 .SetMethod("readData", ReadData) | 221 .SetMethod("readData", ReadData) |
186 | 222 |
187 // TODO(vtl): Change name of "kInvalidHandle", now that there's no such | 223 // TODO(vtl): Change name of "kInvalidHandle", now that there's no such |
188 // C++ constant? | 224 // C++ constant? |
189 .SetValue("kInvalidHandle", mojo::Handle()) | 225 .SetValue("kInvalidHandle", mojo::Handle()) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 .Build(); | 273 .Build(); |
238 | 274 |
239 data->SetObjectTemplate(&g_wrapper_info, templ); | 275 data->SetObjectTemplate(&g_wrapper_info, templ); |
240 } | 276 } |
241 | 277 |
242 return templ->NewInstance(); | 278 return templ->NewInstance(); |
243 } | 279 } |
244 | 280 |
245 } // namespace js | 281 } // namespace js |
246 } // namespace mojo | 282 } // namespace mojo |
OLD | NEW |