1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/shell_runner.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/converter.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/modules/module_registry.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/per_context_data.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/public/context_holder.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/try_catch.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::Context;
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::HandleScope;
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::Isolate;
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::Object;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::ObjectTemplate;
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using v8::Script;
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace gin {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ShellRunnerDelegate::ShellRunnerDelegate() {
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ShellRunnerDelegate::~ShellRunnerDelegate() {
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<ObjectTemplate> ShellRunnerDelegate::GetGlobalTemplate(
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ShellRunner* runner,
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    v8::Isolate* isolate) {
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return v8::Handle<ObjectTemplate>();
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunnerDelegate::DidCreateContext(ShellRunner* runner) {
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunnerDelegate::WillRunScript(ShellRunner* runner) {
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunnerDelegate::DidRunScript(ShellRunner* runner) {
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunnerDelegate::UnhandledException(ShellRunner* runner,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                               TryCatch& try_catch) {
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(false) << try_catch.GetStackTrace();
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ShellRunner::ShellRunner(ShellRunnerDelegate* delegate, Isolate* isolate)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : delegate_(delegate) {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Isolate::Scope isolate_scope(isolate);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HandleScope handle_scope(isolate);
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Handle<v8::Context> context =
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Context::New(isolate, NULL, delegate_->GetGlobalTemplate(this, isolate));
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  context_holder_.reset(new ContextHolder(isolate));
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  context_holder_->SetContext(context);
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerContextData::From(context)->set_runner(this);
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Context::Scope scope(context);
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->DidCreateContext(this);
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ShellRunner::~ShellRunner() {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunner::Run(const std::string& source,
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      const std::string& resource_name) {
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TryCatch try_catch;
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Isolate* isolate = GetContextHolder()->isolate();
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Handle<Script> script = Script::Compile(
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      StringToV8(isolate, source), StringToV8(isolate, resource_name));
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (try_catch.HasCaught()) {
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_->UnhandledException(this, try_catch);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Run(script);
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Value> ShellRunner::Call(v8::Handle<v8::Function> function,
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                        v8::Handle<v8::Value> receiver,
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                        int argc,
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                        v8::Handle<v8::Value> argv[]) {
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TryCatch try_catch;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->WillRunScript(this);
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  v8::Handle<v8::Value> result = function->Call(receiver, argc, argv);
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->DidRunScript(this);
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (try_catch.HasCaught())
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_->UnhandledException(this, try_catch);
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return result;
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ContextHolder* ShellRunner::GetContextHolder() {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return context_holder_.get();
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ShellRunner::Run(v8::Handle<Script> script) {
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TryCatch try_catch;
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->WillRunScript(this);
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  script->Run();
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->DidRunScript(this);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (try_catch.HasCaught()) {
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_->UnhandledException(this, try_catch);
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace gin
113