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

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

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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
« no previous file with comments | « mojo/edk/js/core.h ('k') | mojo/edk/js/drain_data.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/edk/js/core.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "gin/arguments.h"
10 #include "gin/array_buffer.h"
11 #include "gin/converter.h"
12 #include "gin/dictionary.h"
13 #include "gin/function_template.h"
14 #include "gin/handle.h"
15 #include "gin/object_template_builder.h"
16 #include "gin/per_isolate_data.h"
17 #include "gin/public/wrapper_info.h"
18 #include "gin/wrappable.h"
19 #include "mojo/edk/js/drain_data.h"
20 #include "mojo/edk/js/handle.h"
21
22 namespace mojo {
23 namespace js {
24
25 namespace {
26
27 MojoResult CloseHandle(gin::Handle<HandleWrapper> handle) {
28 if (!handle->get().is_valid())
29 return MOJO_RESULT_INVALID_ARGUMENT;
30 handle->Close();
31 return MOJO_RESULT_OK;
32 }
33
34 gin::Dictionary WaitHandle(const gin::Arguments& args,
35 mojo::Handle handle,
36 MojoHandleSignals signals,
37 MojoDeadline deadline) {
38 v8::Isolate* isolate = args.isolate();
39 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate);
40
41 MojoHandleSignalsState signals_state;
42 MojoResult result = mojo::Wait(handle, signals, deadline, &signals_state);
43 dictionary.Set("result", result);
44
45 mojo::WaitManyResult wmv(result, 0);
46 if (!wmv.AreSignalsStatesValid()) {
47 dictionary.Set("signalsState", v8::Null(isolate).As<v8::Value>());
48 } else {
49 gin::Dictionary signalsStateDict = gin::Dictionary::CreateEmpty(isolate);
50 signalsStateDict.Set("satisfiedSignals", signals_state.satisfied_signals);
51 signalsStateDict.Set("satisfiableSignals",
52 signals_state.satisfiable_signals);
53 dictionary.Set("signalsState", signalsStateDict);
54 }
55
56 return dictionary;
57 }
58
59 gin::Dictionary WaitMany(const gin::Arguments& args,
60 const std::vector<mojo::Handle>& handles,
61 const std::vector<MojoHandleSignals>& signals,
62 MojoDeadline deadline) {
63 v8::Isolate* isolate = args.isolate();
64 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate);
65
66 std::vector<MojoHandleSignalsState> signals_states(signals.size());
67 mojo::WaitManyResult wmv =
68 mojo::WaitMany(handles, signals, deadline, &signals_states);
69 dictionary.Set("result", wmv.result);
70 if (wmv.IsIndexValid()) {
71 dictionary.Set("index", wmv.index);
72 } else {
73 dictionary.Set("index", v8::Null(isolate).As<v8::Value>());
74 }
75 if (wmv.AreSignalsStatesValid()) {
76 std::vector<gin::Dictionary> vec;
77 for (size_t i = 0; i < handles.size(); ++i) {
78 gin::Dictionary signalsStateDict = gin::Dictionary::CreateEmpty(isolate);
79 signalsStateDict.Set("satisfiedSignals",
80 signals_states[i].satisfied_signals);
81 signalsStateDict.Set("satisfiableSignals",
82 signals_states[i].satisfiable_signals);
83 vec.push_back(signalsStateDict);
84 }
85 dictionary.Set("signalsState", vec);
86 } else {
87 dictionary.Set("signalsState", v8::Null(isolate).As<v8::Value>());
88 }
89
90 return dictionary;
91 }
92
93 gin::Dictionary CreateMessagePipe(const gin::Arguments& args) {
94 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
95 dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
96
97 MojoHandle handle0 = MOJO_HANDLE_INVALID;
98 MojoHandle handle1 = MOJO_HANDLE_INVALID;
99 MojoResult result = MOJO_RESULT_OK;
100
101 v8::Handle<v8::Value> options_value = args.PeekNext();
102 if (options_value.IsEmpty() || options_value->IsNull() ||
103 options_value->IsUndefined()) {
104 result = MojoCreateMessagePipe(NULL, &handle0, &handle1);
105 } else if (options_value->IsObject()) {
106 gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
107 MojoCreateMessagePipeOptions options;
108 // For future struct_size, we can probably infer that from the presence of
109 // properties in options_dict. For now, it's always 8.
110 options.struct_size = 8;
111 // Ideally these would be optional. But the interface makes it hard to
112 // typecheck them then.
113 if (!options_dict.Get("flags", &options.flags)) {
114 return dictionary;
115 }
116
117 result = MojoCreateMessagePipe(&options, &handle0, &handle1);
118 } else {
119 return dictionary;
120 }
121
122 CHECK_EQ(MOJO_RESULT_OK, result);
123
124 dictionary.Set("result", result);
125 dictionary.Set("handle0", mojo::Handle(handle0));
126 dictionary.Set("handle1", mojo::Handle(handle1));
127 return dictionary;
128 }
129
130 MojoResult WriteMessage(
131 mojo::Handle handle,
132 const gin::ArrayBufferView& buffer,
133 const std::vector<gin::Handle<HandleWrapper> >& handles,
134 MojoWriteMessageFlags flags) {
135 std::vector<MojoHandle> raw_handles(handles.size());
136 for (size_t i = 0; i < handles.size(); ++i)
137 raw_handles[i] = handles[i]->get().value();
138 MojoResult rv = MojoWriteMessage(handle.value(),
139 buffer.bytes(),
140 static_cast<uint32_t>(buffer.num_bytes()),
141 raw_handles.empty() ? NULL : &raw_handles[0],
142 static_cast<uint32_t>(raw_handles.size()),
143 flags);
144 // MojoWriteMessage takes ownership of the handles upon success, so
145 // release them here.
146 if (rv == MOJO_RESULT_OK) {
147 for (size_t i = 0; i < handles.size(); ++i)
148 ignore_result(handles[i]->release());
149 }
150 return rv;
151 }
152
153 gin::Dictionary ReadMessage(const gin::Arguments& args,
154 mojo::Handle handle,
155 MojoReadMessageFlags flags) {
156 uint32_t num_bytes = 0;
157 uint32_t num_handles = 0;
158 MojoResult result = MojoReadMessage(
159 handle.value(), NULL, &num_bytes, NULL, &num_handles, flags);
160 if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) {
161 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
162 dictionary.Set("result", result);
163 return dictionary;
164 }
165
166 v8::Handle<v8::ArrayBuffer> array_buffer =
167 v8::ArrayBuffer::New(args.isolate(), num_bytes);
168 std::vector<mojo::Handle> handles(num_handles);
169
170 gin::ArrayBuffer buffer;
171 ConvertFromV8(args.isolate(), array_buffer, &buffer);
172 CHECK(buffer.num_bytes() == num_bytes);
173
174 result = MojoReadMessage(handle.value(),
175 buffer.bytes(),
176 &num_bytes,
177 handles.empty() ? NULL :
178 reinterpret_cast<MojoHandle*>(&handles[0]),
179 &num_handles,
180 flags);
181
182 CHECK(buffer.num_bytes() == num_bytes);
183 CHECK(handles.size() == num_handles);
184
185 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
186 dictionary.Set("result", result);
187 dictionary.Set("buffer", array_buffer);
188 dictionary.Set("handles", handles);
189 return dictionary;
190 }
191
192 gin::Dictionary CreateDataPipe(const gin::Arguments& args) {
193 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
194 dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
195
196 MojoHandle producer_handle = MOJO_HANDLE_INVALID;
197 MojoHandle consumer_handle = MOJO_HANDLE_INVALID;
198 MojoResult result = MOJO_RESULT_OK;
199
200 v8::Handle<v8::Value> options_value = args.PeekNext();
201 if (options_value.IsEmpty() || options_value->IsNull() ||
202 options_value->IsUndefined()) {
203 result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle);
204 } else if (options_value->IsObject()) {
205 gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
206 MojoCreateDataPipeOptions options;
207 // For future struct_size, we can probably infer that from the presence of
208 // properties in options_dict. For now, it's always 16.
209 options.struct_size = 16;
210 // Ideally these would be optional. But the interface makes it hard to
211 // typecheck them then.
212 if (!options_dict.Get("flags", &options.flags) ||
213 !options_dict.Get("elementNumBytes", &options.element_num_bytes) ||
214 !options_dict.Get("capacityNumBytes", &options.capacity_num_bytes)) {
215 return dictionary;
216 }
217
218 result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle);
219 } else {
220 return dictionary;
221 }
222
223 CHECK_EQ(MOJO_RESULT_OK, result);
224
225 dictionary.Set("result", result);
226 dictionary.Set("producerHandle", mojo::Handle(producer_handle));
227 dictionary.Set("consumerHandle", mojo::Handle(consumer_handle));
228 return dictionary;
229 }
230
231 gin::Dictionary WriteData(const gin::Arguments& args,
232 mojo::Handle handle,
233 const gin::ArrayBufferView& buffer,
234 MojoWriteDataFlags flags) {
235 uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes());
236 MojoResult result =
237 MojoWriteData(handle.value(), buffer.bytes(), &num_bytes, flags);
238 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
239 dictionary.Set("result", result);
240 dictionary.Set("numBytes", num_bytes);
241 return dictionary;
242 }
243
244 gin::Dictionary ReadData(const gin::Arguments& args,
245 mojo::Handle handle,
246 MojoReadDataFlags flags) {
247 uint32_t num_bytes = 0;
248 MojoResult result = MojoReadData(
249 handle.value(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
250 if (result != MOJO_RESULT_OK) {
251 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
252 dictionary.Set("result", result);
253 return dictionary;
254 }
255
256 v8::Handle<v8::ArrayBuffer> array_buffer =
257 v8::ArrayBuffer::New(args.isolate(), num_bytes);
258 gin::ArrayBuffer buffer;
259 ConvertFromV8(args.isolate(), array_buffer, &buffer);
260 CHECK_EQ(num_bytes, buffer.num_bytes());
261
262 result = MojoReadData(handle.value(), buffer.bytes(), &num_bytes, flags);
263 CHECK_EQ(num_bytes, buffer.num_bytes());
264
265 gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
266 dictionary.Set("result", result);
267 dictionary.Set("buffer", array_buffer);
268 return dictionary;
269 }
270
271 // Asynchronously read all of the data available for the specified data pipe
272 // consumer handle until the remote handle is closed or an error occurs. A
273 // Promise is returned whose settled value is an object like this:
274 // {result: core.RESULT_OK, buffer: dataArrayBuffer}. If the read failed,
275 // then the Promise is rejected, the result will be the actual error code,
276 // and the buffer will contain whatever was read before the error occurred.
277 // The drainData data pipe handle argument is closed automatically.
278
279 v8::Handle<v8::Value> DoDrainData(gin::Arguments* args,
280 gin::Handle<HandleWrapper> handle) {
281 return (new DrainData(args->isolate(), handle->release()))->GetPromise();
282 }
283
284 bool IsHandle(gin::Arguments* args, v8::Handle<v8::Value> val) {
285 gin::Handle<mojo::js::HandleWrapper> ignore_handle;
286 return gin::Converter<gin::Handle<mojo::js::HandleWrapper>>::FromV8(
287 args->isolate(), val, &ignore_handle);
288 }
289
290
291 gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
292
293 } // namespace
294
295 const char Core::kModuleName[] = "mojo/public/js/core";
296
297 v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
298 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
299 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
300 &g_wrapper_info);
301
302 if (templ.IsEmpty()) {
303 templ =
304 gin::ObjectTemplateBuilder(isolate)
305 // TODO(mpcomplete): Should these just be methods on the JS Handle
306 // object?
307 .SetMethod("close", CloseHandle)
308 .SetMethod("wait", WaitHandle)
309 .SetMethod("waitMany", WaitMany)
310 .SetMethod("createMessagePipe", CreateMessagePipe)
311 .SetMethod("writeMessage", WriteMessage)
312 .SetMethod("readMessage", ReadMessage)
313 .SetMethod("createDataPipe", CreateDataPipe)
314 .SetMethod("writeData", WriteData)
315 .SetMethod("readData", ReadData)
316 .SetMethod("drainData", DoDrainData)
317 .SetMethod("isHandle", IsHandle)
318
319 .SetValue("RESULT_OK", MOJO_RESULT_OK)
320 .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
321 .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
322 .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
323 .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
324 .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
325 .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
326 .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
327 .SetValue("RESULT_RESOURCE_EXHAUSTED",
328 MOJO_RESULT_RESOURCE_EXHAUSTED)
329 .SetValue("RESULT_FAILED_PRECONDITION",
330 MOJO_RESULT_FAILED_PRECONDITION)
331 .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
332 .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
333 .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
334 .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
335 .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
336 .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
337 .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
338 .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
339
340 .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
341
342 .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
343 .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
344 .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
345 .SetValue("HANDLE_SIGNAL_PEER_CLOSED",
346 MOJO_HANDLE_SIGNAL_PEER_CLOSED)
347
348 .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
349 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
350
351 .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
352
353 .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
354 .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
355 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
356
357 .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
358 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
359 .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
360 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
361
362 .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
363 .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
364 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
365
366 .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
367 .SetValue("READ_DATA_FLAG_ALL_OR_NONE",
368 MOJO_READ_DATA_FLAG_ALL_OR_NONE)
369 .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
370 .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
371 .SetValue("READ_DATA_FLAG_PEEK", MOJO_READ_DATA_FLAG_PEEK)
372 .Build();
373
374 data->SetObjectTemplate(&g_wrapper_info, templ);
375 }
376
377 return templ->NewInstance();
378 }
379
380 } // namespace js
381 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/js/core.h ('k') | mojo/edk/js/drain_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698