Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |