Skip to content

Commit

Permalink
[Mojo] Almost connect mojo_js with hello_world_service
Browse files Browse the repository at this point in the history
This CL connects mojo_js with hello_world_service. After this
CL, the JavaScript and C++ implementations have reached
parity.

BUG=317398

Review URL: https://codereview.chromium.org/82953004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237018 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
abarth@chromium.org committed Nov 25, 2013
1 parent 6a36eff commit 0d72f00
Show file tree
Hide file tree
Showing 24 changed files with 642 additions and 46 deletions.
47 changes: 21 additions & 26 deletions gin/modules/module_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
#include "gin/converter.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
#include "gin/try_catch.h"
#include "gin/runner.h"

using v8::Context;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Handle;
using v8::Isolate;
using v8::Local;
using v8::Object;
Expand Down Expand Up @@ -56,7 +55,7 @@ void Define(const v8::FunctionCallbackInfo<Value>& info) {

std::string id;
std::vector<std::string> dependencies;
Handle<Value> factory;
v8::Handle<Value> factory;

if (args.PeekNext()->IsString())
args.GetNext(&id);
Expand Down Expand Up @@ -88,7 +87,7 @@ Local<FunctionTemplate> GetDefineTemplate(Isolate* isolate) {
return templ;
}

Handle<String> GetHiddenValueKey(Isolate* isolate) {
v8::Handle<String> GetHiddenValueKey(Isolate* isolate) {
return StringToSymbol(isolate, "::gin::ModuleRegistry");
}

Expand All @@ -103,15 +102,15 @@ ModuleRegistry::~ModuleRegistry() {
}

void ModuleRegistry::RegisterGlobals(Isolate* isolate,
Handle<ObjectTemplate> templ) {
v8::Handle<ObjectTemplate> templ) {
templ->Set(StringToSymbol(isolate, "define"), GetDefineTemplate(isolate));
}

ModuleRegistry* ModuleRegistry::From(Handle<Context> context) {
ModuleRegistry* ModuleRegistry::From(v8::Handle<Context> context) {
Isolate* isolate = context->GetIsolate();
Handle<String> key = GetHiddenValueKey(isolate);
Handle<Value> value = context->Global()->GetHiddenValue(key);
Handle<External> external;
v8::Handle<String> key = GetHiddenValueKey(isolate);
v8::Handle<Value> value = context->Global()->GetHiddenValue(key);
v8::Handle<External> external;
if (value.IsEmpty() || !ConvertFromV8(value, &external)) {
PerContextData* data = PerContextData::From(context);
if (!data)
Expand All @@ -126,7 +125,7 @@ ModuleRegistry* ModuleRegistry::From(Handle<Context> context) {

void ModuleRegistry::AddBuiltinModule(Isolate* isolate,
const std::string& id,
Handle<ObjectTemplate> templ) {
v8::Handle<ObjectTemplate> templ) {
DCHECK(!id.empty());
RegisterModule(isolate, id, templ->NewInstance());
}
Expand All @@ -138,19 +137,19 @@ void ModuleRegistry::AddPendingModule(Isolate* isolate,

void ModuleRegistry::RegisterModule(Isolate* isolate,
const std::string& id,
Handle<Value> module) {
v8::Handle<Value> module) {
if (id.empty() || module.IsEmpty())
return;

unsatisfied_dependencies_.erase(id);
available_modules_.insert(id);
Handle<Object> modules = Local<Object>::New(isolate, modules_);
v8::Handle<Object> modules = Local<Object>::New(isolate, modules_);
modules->Set(StringToSymbol(isolate, id), module);
}

void ModuleRegistry::Detach(Handle<Context> context) {
void ModuleRegistry::Detach(v8::Handle<Context> context) {
context->Global()->SetHiddenValue(GetHiddenValueKey(context->GetIsolate()),
Handle<Value>());
v8::Handle<Value>());
}

bool ModuleRegistry::CheckDependencies(PendingModule* pending) {
Expand All @@ -170,26 +169,22 @@ void ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) {
if (!pending->id.empty() && available_modules_.count(pending->id))
return; // We've already loaded this module.

Handle<Object> modules = Local<Object>::New(isolate, modules_);
v8::Handle<Object> modules = Local<Object>::New(isolate, modules_);
uint32_t argc = static_cast<uint32_t>(pending->dependencies.size());
std::vector<Handle<Value> > argv(argc);
std::vector<v8::Handle<Value> > argv(argc);
for (uint32_t i = 0; i < argc; ++i) {
Handle<String> key = StringToSymbol(isolate, pending->dependencies[i]);
v8::Handle<String> key = StringToSymbol(isolate, pending->dependencies[i]);
DCHECK(modules->HasOwnProperty(key));
argv[i] = modules->Get(key);
}

Handle<Value> module = Local<Value>::New(isolate, pending->factory);
v8::Handle<Value> module = Local<Value>::New(isolate, pending->factory);

Handle<Function> factory;
v8::Handle<Function> factory;
if (ConvertFromV8(module, &factory)) {
Handle<Object> global = isolate->GetCurrentContext()->Global();
{
gin::TryCatch try_catch;
module = factory->Call(global, argc, argv.data());
if (try_catch.HasCaught())
return; // TODO(abarth): What should we do with the exception?
}
PerContextData* data = PerContextData::From(isolate->GetCurrentContext());
Runner* runner = data->runner();
module = runner->Call(factory, runner->global(), argc, argv.data());
if (pending->id.empty())
ConvertFromV8(factory->GetScriptOrigin().ResourceName(), &pending->id);
}
Expand Down
3 changes: 1 addition & 2 deletions gin/modules/module_runner_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ void ModuleRunnerDelegate::DidCreateContext(Runner* runner) {
}
}

void ModuleRunnerDelegate::DidRunScript(Runner* runner,
v8::Handle<v8::Script> script) {
void ModuleRunnerDelegate::DidRunScript(Runner* runner) {
ModuleRegistry* registry = ModuleRegistry::From(runner->context());
registry->AttemptToLoadMoreModules(runner->isolate());
module_provider_.AttempToLoadModules(
Expand Down
3 changes: 1 addition & 2 deletions gin/modules/module_runner_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class ModuleRunnerDelegate : public RunnerDelegate {
virtual v8::Handle<v8::ObjectTemplate> GetGlobalTemplate(
Runner* runner) OVERRIDE;
virtual void DidCreateContext(Runner* runner) OVERRIDE;
virtual void DidRunScript(Runner* runner,
v8::Handle<v8::Script> script) OVERRIDE;
virtual void DidRunScript(Runner* runner) OVERRIDE;

BuiltinModuleMap builtin_modules_;
FileModuleProvider module_provider_;
Expand Down
3 changes: 2 additions & 1 deletion gin/per_context_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ ContextSupplement::ContextSupplement() {
ContextSupplement::~ContextSupplement() {
}

PerContextData::PerContextData(v8::Handle<v8::Context> context) {
PerContextData::PerContextData(v8::Handle<v8::Context> context)
: runner_(NULL) {
context->SetAlignedPointerInEmbedderData(kEncodedValueIndex, this);
}

Expand Down
6 changes: 6 additions & 0 deletions gin/per_context_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace gin {

class Runner;

class ContextSupplement {
public:
ContextSupplement();
Expand All @@ -32,11 +34,15 @@ class PerContextData {
static PerContextData* From(v8::Handle<v8::Context>);
void Detach(v8::Handle<v8::Context> context);

void set_runner(Runner* runner) { runner_ = runner; }
Runner* runner() const { return runner_; }

void AddSupplement(scoped_ptr<ContextSupplement> supplement);

private:
typedef ScopedVector<ContextSupplement> SuplementVector;

Runner* runner_;
SuplementVector supplements_;

DISALLOW_COPY_AND_ASSIGN(PerContextData);
Expand Down
1 change: 0 additions & 1 deletion gin/per_isolate_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "gin/public/gin_embedders.h"

using v8::Eternal;
using v8::Handle;
using v8::Isolate;
using v8::Local;
using v8::Object;
Expand Down
35 changes: 29 additions & 6 deletions gin/runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "gin/runner.h"

#include "gin/converter.h"
#include "gin/per_context_data.h"
#include "gin/try_catch.h"

using v8::Context;
Expand All @@ -29,10 +30,10 @@ v8::Handle<ObjectTemplate> RunnerDelegate::GetGlobalTemplate(Runner* runner) {
void RunnerDelegate::DidCreateContext(Runner* runner) {
}

void RunnerDelegate::WillRunScript(Runner* runner, v8::Handle<Script> script) {
void RunnerDelegate::WillRunScript(Runner* runner) {
}

void RunnerDelegate::DidRunScript(Runner* runner, v8::Handle<Script> script) {
void RunnerDelegate::DidRunScript(Runner* runner) {
}

void RunnerDelegate::UnhandledException(Runner* runner, TryCatch& try_catch) {
Expand All @@ -44,9 +45,13 @@ Runner::Runner(RunnerDelegate* delegate, Isolate* isolate)
weak_factory_(this) {
v8::Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
SetContext(Context::New(isolate, NULL, delegate_->GetGlobalTemplate(this)));
v8::Handle<v8::Context> context =
Context::New(isolate, NULL, delegate_->GetGlobalTemplate(this));

v8::Context::Scope scope(context());
SetContext(context);
PerContextData::From(context)->set_runner(this);

v8::Context::Scope scope(context);
delegate_->DidCreateContext(this);
}

Expand All @@ -59,13 +64,31 @@ void Runner::Run(const std::string& script) {

void Runner::Run(v8::Handle<Script> script) {
TryCatch try_catch;
delegate_->WillRunScript(this, script);
delegate_->WillRunScript(this);

script->Run();
delegate_->DidRunScript(this, script);

delegate_->DidRunScript(this);
if (try_catch.HasCaught())
delegate_->UnhandledException(this, try_catch);
}

v8::Handle<v8::Value> Runner::Call(v8::Handle<v8::Function> function,
v8::Handle<v8::Value> receiver,
int argc,
v8::Handle<v8::Value> argv[]) {
TryCatch try_catch;
delegate_->WillRunScript(this);

v8::Handle<v8::Value> result = function->Call(receiver, argc, argv);

delegate_->DidRunScript(this);
if (try_catch.HasCaught())
delegate_->UnhandledException(this, try_catch);

return result;
}

Runner::Scope::Scope(Runner* runner)
: isolate_scope_(runner->isolate()),
handle_scope_(runner->isolate()),
Expand Down
9 changes: 7 additions & 2 deletions gin/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class RunnerDelegate {
// Returns the template for the global object.
virtual v8::Handle<v8::ObjectTemplate> GetGlobalTemplate(Runner* runner);
virtual void DidCreateContext(Runner* runner);
virtual void WillRunScript(Runner* runner, v8::Handle<v8::Script> script);
virtual void DidRunScript(Runner* runner, v8::Handle<v8::Script> script);
virtual void WillRunScript(Runner* runner);
virtual void DidRunScript(Runner* runner);
virtual void UnhandledException(Runner* runner, TryCatch& try_catch);
};

Expand All @@ -36,6 +36,11 @@ class Runner : public ContextHolder {
void Run(const std::string& script);
void Run(v8::Handle<v8::Script> script);

v8::Handle<v8::Value> Call(v8::Handle<v8::Function> function,
v8::Handle<v8::Value> receiver,
int argc,
v8::Handle<v8::Value> argv[]);

v8::Handle<v8::Object> global() const {
return context()->Global();
}
Expand Down
6 changes: 6 additions & 0 deletions gin/wrappable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ Wrappable::~Wrappable() {
wrapper_.Reset();
}

v8::Handle<v8::Object> Wrappable::GetWrapper(v8::Isolate* isolate) {
v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, this);
DCHECK(wrapper->IsObject());
return v8::Handle<v8::Object>::Cast(wrapper);
}

void Wrappable::WeakCallback(
const v8::WeakCallbackData<v8::Object, Wrappable>& data) {
Wrappable* wrappable = data.GetParameter();
Expand Down
2 changes: 2 additions & 0 deletions gin/wrappable.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Wrappable : public base::RefCounted<Wrappable> {
public:
virtual WrapperInfo* GetWrapperInfo() = 0;

v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate);

protected:
Wrappable();
virtual ~Wrappable();
Expand Down
1 change: 0 additions & 1 deletion mojo/apps/js/DEPS
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
include_rules = [
"+gin",
"+v8",
"-base",
]
54 changes: 54 additions & 0 deletions mojo/apps/js/bootstrap.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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/bootstrap.h"

#include "base/message_loop/message_loop.h"
#include "gin/per_isolate_data.h"
#include "mojo/public/bindings/js/handle.h"

namespace mojo {
namespace apps {

namespace {

void Quit(const v8::FunctionCallbackInfo<v8::Value>& info) {
base::MessageLoop::current()->QuitNow();
}

MojoHandle g_initial_handle = MOJO_HANDLE_INVALID;

gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };

} // namespace

const char Bootstrap::kModuleName[] = "mojo/apps/js/bootstrap";

v8::Local<v8::ObjectTemplate> Bootstrap::GetTemplate(v8::Isolate* isolate) {
gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
&g_wrapper_info);

if (templ.IsEmpty()) {
templ = v8::ObjectTemplate::New();
templ->Set(gin::StringToSymbol(isolate, "quit"),
v8::FunctionTemplate::New(Quit));

// Don't forget to call SetInitialHandle before getting the template.
DCHECK(g_initial_handle != MOJO_HANDLE_INVALID);
templ->Set(gin::StringToSymbol(isolate, "initialHandle"),
gin::ConvertToV8(isolate, g_initial_handle));

data->SetObjectTemplate(&g_wrapper_info, templ);
}

return templ;
}

void Bootstrap::SetInitialHandle(MojoHandle pipe) {
g_initial_handle = pipe;
}

} // namespace apps
} // namespace mojo
26 changes: 26 additions & 0 deletions mojo/apps/js/bootstrap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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_BOOTSTRAP_H_
#define MOJO_APPS_JS_BOOTSTRAP_H_

#include "mojo/public/system/core.h"
#include "v8/include/v8.h"

namespace mojo {
namespace apps {

class Bootstrap {
public:
static const char kModuleName[];
static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate);

// Must be called before the first call to GetTemplate.
static void SetInitialHandle(MojoHandle handle);
};

} // namespace apps
} // namespace mojo

#endif // MOJO_APPS_JS_BOOTSTRAP_H_
Loading

0 comments on commit 0d72f00

Please sign in to comment.