1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// Copyright (c) 2012 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 "chrome/renderer/module_system.h"
#include "base/bind.h"
#include "chrome/renderer/static_v8_external_string_resource.h"
#include "grit/renderer_resources.h"
#include "ui/base/resource/resource_bundle.h"
namespace {
} // namespace
ModuleSystem::ModuleSystem(SourceMap* source_map)
: source_map_(source_map),
natives_enabled_(true) {
RouteFunction("GetSource",
base::Bind(&ModuleSystem::GetSource, base::Unretained(this)));
RouteFunction("GetNative",
base::Bind(&ModuleSystem::GetNative, base::Unretained(this)));
}
ModuleSystem::~ModuleSystem() {
}
void ModuleSystem::Require(const std::string& module_name) {
v8::HandleScope handle_scope;
v8::Handle<v8::Value> argv[] = {
v8::String::New(module_name.c_str()),
};
v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
GetOrCreateRequire()->Call(global, arraysize(argv), argv);
}
void ModuleSystem::RegisterNativeHandler(const std::string& name,
scoped_ptr<NativeHandler> native_handler) {
native_handler_map_[name] =
linked_ptr<NativeHandler>(native_handler.release());
}
void ModuleSystem::RunString(const std::string& code, const std::string& name) {
v8::HandleScope handle_scope;
RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str()));
}
v8::Handle<v8::Function> ModuleSystem::CreateRequire() {
v8::HandleScope handle_scope;
v8::Handle<v8::Object> bootstrap = NewInstance();
// NOTE v8 takes ownership of the StaticV8ExternalAsciiStringResource.
v8::Handle<v8::String> source = v8::String::NewExternal(
new StaticV8ExternalAsciiStringResource(GetResource(IDR_REQUIRE_JS)));
v8::Handle<v8::Value> result = RunString(source,
v8::String::New("require.js"));
v8::Handle<v8::Function> require_factory =
v8::Handle<v8::Function>::Cast(result);
CHECK(!require_factory.IsEmpty())
<< "require.js should define a function that returns a require() "
<< "function";
v8::Handle<v8::Value> argv[] = {
bootstrap,
};
v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
v8::Handle<v8::Value> require = require_factory->Call(
global, arraysize(argv), argv);
global->SetHiddenValue(v8::String::New("require"), require);
return handle_scope.Close(v8::Handle<v8::Function>::Cast(require));
}
v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code,
v8::Handle<v8::String> name) {
v8::HandleScope handle_scope;
return handle_scope.Close(v8::Script::New(code, name)->Run());
}
v8::Handle<v8::Value> ModuleSystem::GetSource(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
v8::HandleScope handle_scope;
std::string module_name = *v8::String::AsciiValue(args[0]->ToString());
if (!source_map_->Contains(module_name))
return v8::Undefined();
return handle_scope.Close(source_map_->GetSource(module_name));
}
v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
if (!natives_enabled_)
return ThrowException("Natives disabled");
std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
if (i == native_handler_map_.end())
return v8::Undefined();
return i->second->NewInstance();
}
base::StringPiece ModuleSystem::GetResource(int resourceId) {
const ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
return resource_bundle.GetRawDataResource(resourceId);
}
v8::Handle<v8::Value> ModuleSystem::ThrowException(const std::string& message) {
return v8::ThrowException(v8::String::New(message.c_str()));
}
v8::Handle<v8::Function> ModuleSystem::GetOrCreateRequire() {
v8::HandleScope handle_scope;
v8::Handle<v8::String> require_string = v8::String::New("require");
v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
{
v8::Handle<v8::Function> require =
v8::Handle<v8::Function>::Cast(global->GetHiddenValue(require_string));
if (!require.IsEmpty())
return handle_scope.Close(require);
}
v8::Handle<v8::Function> require(CreateRequire());
global->SetHiddenValue(require_string, require);
return handle_scope.Close(require);
}
|