diff options
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/apps/js/DEPS | 1 | ||||
-rw-r--r-- | mojo/apps/js/main.cc | 4 | ||||
-rw-r--r-- | mojo/apps/js/v8_environment.cc | 49 | ||||
-rw-r--r-- | mojo/apps/js/v8_environment.h | 16 | ||||
-rw-r--r-- | mojo/mojo.gyp | 45 | ||||
-rw-r--r-- | mojo/public/bindings/js/DEPS | 5 | ||||
-rw-r--r-- | mojo/public/bindings/js/core.cc | 161 | ||||
-rw-r--r-- | mojo/public/bindings/js/core.h | 18 | ||||
-rw-r--r-- | mojo/public/bindings/js/handle.cc | 19 | ||||
-rw-r--r-- | mojo/public/bindings/js/handle.h | 23 | ||||
-rw-r--r-- | mojo/public/bindings/js/mojo.cc | 34 | ||||
-rw-r--r-- | mojo/public/bindings/js/mojo.h | 18 | ||||
-rw-r--r-- | mojo/public/bindings/js/mojo_unittests.js | 8 | ||||
-rw-r--r-- | mojo/public/bindings/js/runner_delegate.cc | 23 | ||||
-rw-r--r-- | mojo/public/bindings/js/runner_delegate.h | 29 | ||||
-rw-r--r-- | mojo/public/bindings/js/test/DEPS | 3 | ||||
-rw-r--r-- | mojo/public/bindings/js/test/harness.cc | 69 |
17 files changed, 454 insertions, 71 deletions
diff --git a/mojo/apps/js/DEPS b/mojo/apps/js/DEPS index 719fd94..0b70f92 100644 --- a/mojo/apps/js/DEPS +++ b/mojo/apps/js/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+gin", "+v8", "-base", ] diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc index 8e57371..6f8cdb3 100644 --- a/mojo/apps/js/main.cc +++ b/mojo/apps/js/main.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/apps/js/v8_environment.h" +#include "gin/initialize.h" #include "mojo/public/system/core.h" #include "mojo/public/system/macros.h" @@ -18,7 +18,7 @@ extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain( mojo::Handle pipe) { - mojo::apps::InitializeV8(); + gin::Initialize(); // TODO(abarth): Load JS off the network and execute it. return MOJO_RESULT_OK; } diff --git a/mojo/apps/js/v8_environment.cc b/mojo/apps/js/v8_environment.cc deleted file mode 100644 index 1b4ee83..0000000 --- a/mojo/apps/js/v8_environment.cc +++ /dev/null @@ -1,49 +0,0 @@ -// 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 "mojo/apps/js/v8_environment.h" - -#include <stdlib.h> -#include <string.h> - -#include "mojo/public/system/macros.h" -#include "v8/include/v8.h" - -namespace mojo { -namespace apps { - -namespace { - -class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { - virtual void* Allocate(size_t length) MOJO_OVERRIDE { - return calloc(1, length); - } - virtual void* AllocateUninitialized(size_t length) MOJO_OVERRIDE { - return malloc(length); - } - virtual void Free(void* data, size_t length) MOJO_OVERRIDE { - free(data); - } -}; - -bool GenerateEntropy(unsigned char* buffer, size_t amount) { - // TODO(abarth): Mojo needs a source of entropy. - // https://code.google.com/p/chromium/issues/detail?id=316387 - return false; -} - -const char kFlags[] = "--use_strict --harmony"; - -} - -void InitializeV8() { - v8::V8::SetArrayBufferAllocator(new ArrayBufferAllocator()); - v8::V8::InitializeICU(); - v8::V8::SetFlagsFromString(kFlags, strlen(kFlags)); - v8::V8::SetEntropySource(&GenerateEntropy); - v8::V8::Initialize(); -} - -} // namespace apps -} // mojo diff --git a/mojo/apps/js/v8_environment.h b/mojo/apps/js/v8_environment.h deleted file mode 100644 index 88d1963..0000000 --- a/mojo/apps/js/v8_environment.h +++ /dev/null @@ -1,16 +0,0 @@ -// 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 MOJO_APPS_JS_V8_ENVIRONMENT_H_ -#define MOJO_APPS_JS_V8_ENVIRONMENT_H_ - -namespace mojo { -namespace apps { - -void InitializeV8(); - -} // namespace apps -} // mojo - -#endif // MOJO_APPS_JS_V8_ENVIRONMENT_H_ diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index 46d3f94..a01aa88 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -25,7 +25,9 @@ 'sample_app', 'mojo_bindings', 'mojo_bindings_test', - 'native_viewport', + 'mojo_js_bindings', + 'mojo_js_bindings_unittests', + 'mojo_bindings', ], }, { @@ -288,12 +290,10 @@ '..' ], 'dependencies': [ - '../v8/tools/gyp/v8.gyp:v8', + 'mojo_js_bindings', ], 'sources': [ 'apps/js/main.cc', - 'apps/js/v8_environment.cc', - 'apps/js/v8_environment.h', ], }, { @@ -353,6 +353,43 @@ 'public/bindings/sample/sample_test.cc', ], }, + { + 'target_name': 'mojo_js_bindings', + 'type': 'static_library', + 'include_dirs': [ + '..' + ], + 'dependencies': [ + '../gin/gin.gyp:gin', + 'mojo_system', + ], + 'export_dependent_settings': [ + '../gin/gin.gyp:gin', + ], + 'sources': [ + 'public/bindings/js/core.cc', + 'public/bindings/js/core.h', + 'public/bindings/js/handle.cc', + 'public/bindings/js/handle.h', + 'public/bindings/js/mojo.cc', + 'public/bindings/js/mojo.h', + 'public/bindings/js/runner_delegate.cc', + 'public/bindings/js/runner_delegate.h', + ], + }, + { + 'target_name': 'mojo_js_bindings_unittests', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:run_all_unittests', + '../gin/gin.gyp:gin_test', + 'mojo_js_bindings', + ], + 'sources': [ + '../gin/test/run_all_unittests.cc', + 'public/bindings/js/test/harness.cc', + ], + }, { 'target_name': 'native_viewport', 'type': 'static_library', diff --git a/mojo/public/bindings/js/DEPS b/mojo/public/bindings/js/DEPS new file mode 100644 index 0000000..ac120ba --- /dev/null +++ b/mojo/public/bindings/js/DEPS @@ -0,0 +1,5 @@ +include_rules = [ + "+gin", + "+testing", + "+v8", +] diff --git a/mojo/public/bindings/js/core.cc b/mojo/public/bindings/js/core.cc new file mode 100644 index 0000000..fadbf75 --- /dev/null +++ b/mojo/public/bindings/js/core.cc @@ -0,0 +1,161 @@ +// 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 "mojo/public/bindings/js/core.h" + +#include "gin/arguments.h" +#include "gin/array_buffer.h" +#include "gin/converter.h" +#include "gin/dictionary.h" +#include "gin/per_isolate_data.h" +#include "gin/wrapper_info.h" +#include "mojo/public/bindings/js/handle.h" + +namespace mojo { +namespace js { + +namespace { + +void Close(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle = mojo::kInvalidHandle; + if (!args.GetNext(&handle)) + return args.ThrowError(); + + args.Return(mojo::Close(handle)); +} + +void Wait(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle = mojo::kInvalidHandle; + MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE; + MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE; + + if (!args.GetNext(&handle) || + !args.GetNext(&flags) || + !args.GetNext(&deadline)) { + return args.ThrowError(); + } + + args.Return(mojo::Wait(handle, flags, deadline)); +} + +void WaitMany(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + std::vector<mojo::Handle> handles; + std::vector<MojoWaitFlags> flags; + MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE; + + if (!args.GetNext(&handles) || + !args.GetNext(&flags) || + !args.GetNext(&deadline)) { + return args.ThrowError(); + } + + if (handles.size() != flags.size()) + return args.ThrowTypeError("Arrays must have the same length."); + + args.Return(mojo::WaitMany(handles.data(), flags.data(), + handles.size(), deadline)); +} + +void CreateMessagePipe(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle_0 = mojo::kInvalidHandle; + mojo::Handle handle_1 = mojo::kInvalidHandle; + MojoResult result = mojo::CreateMessagePipe(&handle_0, &handle_1); + + gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(info.GetIsolate()); + dictionary.Set("result", result); + dictionary.Set("handle0", handle_0); + dictionary.Set("handle1", handle_1); + args.Return(dictionary); +} + +void WriteMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle = mojo::kInvalidHandle; + gin::ArrayBufferView buffer(args.isolate()); + std::vector<mojo::Handle> handles; + MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE; + + if (!args.GetNext(&handle) || + !args.GetNext(&buffer) || + !args.GetNext(&handles) || + !args.GetNext(&flags)) { + return args.ThrowError(); + } + + args.Return(mojo::WriteMessage(handle, buffer.bytes(), buffer.num_bytes(), + handles.data(), handles.size(), flags)); +} + +void ReadMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle = mojo::kInvalidHandle; + gin::ArrayBufferView buffer(args.isolate()); + uint32_t num_handles = 0; + MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE; + + if (!args.GetNext(&handle) || + !args.GetNext(&buffer) || + !args.GetNext(&num_handles) || + !args.GetNext(&flags)) { + return args.ThrowError(); + } + + uint32_t num_bytes = buffer.num_bytes(); + std::vector<mojo::Handle> handles(num_handles); + MojoResult result = mojo::ReadMessage(handle, buffer.bytes(), &num_bytes, + handles.data(), &num_handles, flags); + handles.resize(num_handles); + + // TODO(abarth): We should benchmark this codepath to make sure it's ok to + // allocate all this memory on each read. + gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(info.GetIsolate()); + dictionary.Set("result", result); + dictionary.Set("bytesRead", num_bytes); + dictionary.Set("handles", handles); + args.Return(dictionary); +} + +gin::WrapperInfo g_core_wrapper_info = {}; + +} + +v8::Local<v8::ObjectTemplate> GetCoreTemplate(v8::Isolate* isolate) { + gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); + v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( + &g_core_wrapper_info); + + if (templ.IsEmpty()) { + templ = v8::ObjectTemplate::New(); + + templ->Set(gin::StringToSymbol(isolate, "close"), + v8::FunctionTemplate::New(Close)); + templ->Set(gin::StringToSymbol(isolate, "wait"), + v8::FunctionTemplate::New(Wait)); + templ->Set(gin::StringToSymbol(isolate, "waitMany"), + v8::FunctionTemplate::New(WaitMany)); + templ->Set(gin::StringToSymbol(isolate, "createMessagePipe"), + v8::FunctionTemplate::New(CreateMessagePipe)); + templ->Set(gin::StringToSymbol(isolate, "writeMessage"), + v8::FunctionTemplate::New(WriteMessage)); + templ->Set(gin::StringToSymbol(isolate, "readMessage"), + v8::FunctionTemplate::New(ReadMessage)); + + data->SetObjectTemplate(&g_core_wrapper_info, templ); + } + + return templ; +} + +} // namespace js +} // namespace mojo diff --git a/mojo/public/bindings/js/core.h b/mojo/public/bindings/js/core.h new file mode 100644 index 0000000..32cd0aa --- /dev/null +++ b/mojo/public/bindings/js/core.h @@ -0,0 +1,18 @@ +// 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 MOJO_PUBLIC_BINDINGS_JS_CORE_H_ +#define MOJO_PUBLIC_BINDINGS_JS_CORE_H_ + +#include "v8/include/v8.h" + +namespace mojo { +namespace js { + +v8::Local<v8::ObjectTemplate> GetCoreTemplate(v8::Isolate* isolate); + +} // namespace js +} // namespace mojo + +#endif // MOJO_PUBLIC_BINDINGS_JS_CORE_H_ diff --git a/mojo/public/bindings/js/handle.cc b/mojo/public/bindings/js/handle.cc new file mode 100644 index 0000000..f52ef1c --- /dev/null +++ b/mojo/public/bindings/js/handle.cc @@ -0,0 +1,19 @@ +// 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 "mojo/public/bindings/js/handle.h" + +namespace gin { + +v8::Handle<v8::Value> Converter<mojo::Handle>::ToV8(v8::Isolate* isolate, + mojo::Handle val) { + return Converter<MojoHandle>::ToV8(isolate, val.value); +} + +bool Converter<mojo::Handle>::FromV8(v8::Handle<v8::Value> val, + mojo::Handle* out) { + return Converter<MojoHandle>::FromV8(val, &out->value); +} + +} // namespace gin diff --git a/mojo/public/bindings/js/handle.h b/mojo/public/bindings/js/handle.h new file mode 100644 index 0000000..16a4e81 --- /dev/null +++ b/mojo/public/bindings/js/handle.h @@ -0,0 +1,23 @@ +// 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 MOJO_PUBLIC_BINDINGS_JS_HANDLE_H_ +#define MOJO_PUBLIC_BINDINGS_JS_HANDLE_H_ + +#include "gin/converter.h" +#include "mojo/public/system/core.h" + +namespace gin { + +template<> +struct Converter<mojo::Handle> { + static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, + mojo::Handle val); + static bool FromV8(v8::Handle<v8::Value> val, + mojo::Handle* out); +}; + +} // namespace gin + +#endif // MOJO_PUBLIC_BINDINGS_JS_HANDLE_H_ diff --git a/mojo/public/bindings/js/mojo.cc b/mojo/public/bindings/js/mojo.cc new file mode 100644 index 0000000..a380bb6 --- /dev/null +++ b/mojo/public/bindings/js/mojo.cc @@ -0,0 +1,34 @@ +// 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 "mojo/public/bindings/js/mojo.h" + +#include "gin/converter.h" +#include "gin/per_isolate_data.h" +#include "gin/wrapper_info.h" +#include "mojo/public/bindings/js/core.h" + +namespace mojo { +namespace js { + +namespace { + +gin::WrapperInfo g_mojo_wrapper_info = {}; + +} + +v8::Local<v8::ObjectTemplate> GetMojoTemplate(v8::Isolate* isolate) { + gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); + v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( + &g_mojo_wrapper_info); + if (templ.IsEmpty()) { + templ = v8::ObjectTemplate::New(); + templ->Set(gin::StringToSymbol(isolate, "core"), GetCoreTemplate(isolate)); + data->SetObjectTemplate(&g_mojo_wrapper_info, templ); + } + return templ; +} + +} // namespace js +} // namespace mojo diff --git a/mojo/public/bindings/js/mojo.h b/mojo/public/bindings/js/mojo.h new file mode 100644 index 0000000..95d6e13 --- /dev/null +++ b/mojo/public/bindings/js/mojo.h @@ -0,0 +1,18 @@ +// 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 MOJO_PUBLIC_BINDINGS_JS_MOJO_H_ +#define MOJO_PUBLIC_BINDINGS_JS_MOJO_H_ + +#include "v8/include/v8.h" + +namespace mojo { +namespace js { + +v8::Local<v8::ObjectTemplate> GetMojoTemplate(v8::Isolate* isolate); + +} // namespace js +} // namespace mojo + +#endif // MOJO_PUBLIC_BINDINGS_JS_MOJO_H_ diff --git a/mojo/public/bindings/js/mojo_unittests.js b/mojo/public/bindings/js/mojo_unittests.js new file mode 100644 index 0000000..1e24ed8 --- /dev/null +++ b/mojo/public/bindings/js/mojo_unittests.js @@ -0,0 +1,8 @@ +// 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. + +function main(mojo) { + mojo.gtest.expectTrue(mojo.core, "mojo.core"); + mojo.gtest.expectFalse(mojo.foo, "mojo.foo"); +} diff --git a/mojo/public/bindings/js/runner_delegate.cc b/mojo/public/bindings/js/runner_delegate.cc new file mode 100644 index 0000000..f990caa --- /dev/null +++ b/mojo/public/bindings/js/runner_delegate.cc @@ -0,0 +1,23 @@ +// 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 "mojo/public/bindings/js/runner_delegate.h" + +#include "mojo/public/bindings/js/mojo.h" + +namespace mojo { +namespace js { + +RunnerDelegate::RunnerDelegate() { +} + +RunnerDelegate::~RunnerDelegate() { +} + +v8::Handle<v8::Object> RunnerDelegate::CreateRootObject(gin::Runner* runner) { + return GetMojoTemplate(runner->isolate())->NewInstance(); +} + +} // namespace js +} // namespace mojo diff --git a/mojo/public/bindings/js/runner_delegate.h b/mojo/public/bindings/js/runner_delegate.h new file mode 100644 index 0000000..8bacf44 --- /dev/null +++ b/mojo/public/bindings/js/runner_delegate.h @@ -0,0 +1,29 @@ +// 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 MOJO_PUBLIC_BINDINGS_JS_RUNNER_H_ +#define MOJO_PUBLIC_BINDINGS_JS_RUNNER_H_ + +#include "gin/runner.h" +#include "mojo/public/system/macros.h" + +namespace mojo { +namespace js { + +class RunnerDelegate : public gin::RunnerDelegate { + public: + RunnerDelegate(); + virtual ~RunnerDelegate(); + + virtual v8::Handle<v8::Object> CreateRootObject( + gin::Runner* runner) MOJO_OVERRIDE; + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(RunnerDelegate); +}; + +} // namespace js +} // namespace mojo + +#endif // MOJO_PUBLIC_BINDINGS_JS_RUNNER_H_ diff --git a/mojo/public/bindings/js/test/DEPS b/mojo/public/bindings/js/test/DEPS new file mode 100644 index 0000000..5cd0867 --- /dev/null +++ b/mojo/public/bindings/js/test/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+base", +] diff --git a/mojo/public/bindings/js/test/harness.cc b/mojo/public/bindings/js/test/harness.cc new file mode 100644 index 0000000..b4b81f4 --- /dev/null +++ b/mojo/public/bindings/js/test/harness.cc @@ -0,0 +1,69 @@ +// 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 "base/file_util.h" +#include "base/path_service.h" +#include "gin/converter.h" +#include "gin/runner.h" +#include "gin/test/gtest.h" +#include "mojo/public/bindings/js/runner_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" + +using v8::Isolate; +using v8::Object; +using v8::Script; +using v8::Value; + +namespace mojo { +namespace js { +namespace { + +class TestRunnerDelegate : public RunnerDelegate { + public: + virtual ~TestRunnerDelegate() {} + + virtual v8::Handle<Object> CreateRootObject( + gin::Runner* runner) MOJO_OVERRIDE { + v8::Handle<Object> root = RunnerDelegate::CreateRootObject(runner); + root->Set(gin::StringToSymbol(runner->isolate(), "gtest"), + gin::GetGTestTemplate(runner->isolate())->NewInstance()); + return root; + } +}; + +void RunTestFromFile(const base::FilePath& path) { + EXPECT_TRUE(base::PathExists(path)) << path.LossyDisplayName(); + std::string source; + EXPECT_TRUE(ReadFileToString(path, &source)); + Isolate* isolate = Isolate::GetCurrent(); + + TestRunnerDelegate delegate; + gin::Runner runner(&delegate, isolate); + gin::Runner::Scope scope(&runner); + + v8::TryCatch try_catch; + runner.Run(Script::New(gin::StringToV8(isolate, source))); + + EXPECT_FALSE(try_catch.HasCaught()); +} + +void RunTest(std::string test) { + base::FilePath path; + PathService::Get(base::DIR_SOURCE_ROOT, &path); + path = path.AppendASCII("mojo") + .AppendASCII("public") + .AppendASCII("bindings") + .AppendASCII("js") + .AppendASCII(test); + RunTestFromFile(path); +} + +// TODO(abarth): Should we autogenerate these stubs from GYP? +TEST(Harness, mojo_unittests_js) { + RunTest("mojo_unittests.js"); +} + +} // namespace +} // namespace js +} // namespace mojo |