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