Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: chrome/renderer/extensions/module_system.cc

Issue 11571014: Lazy load chrome.* APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: android compilation Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/module_system.h" 5 #include "chrome/renderer/extensions/module_system.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/alias.h"
8 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/string_util.h"
11 #include "base/stringprintf.h"
12 #include "chrome/common/extensions/extension_messages.h"
13 #include "chrome/renderer/extensions/chrome_v8_context.h"
14 #include "content/public/renderer/render_view.h"
9 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSup pression.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSup pression.h"
10 16
11 namespace { 17 namespace {
12 18
13 const char* kModuleSystem = "module_system"; 19 const char* kModuleSystem = "module_system";
14 const char* kModuleName = "module_name"; 20 const char* kModuleName = "module_name";
15 const char* kModuleField = "module_field"; 21 const char* kModuleField = "module_field";
16 const char* kModulesField = "modules"; 22 const char* kModulesField = "modules";
17 23
18 } // namespace 24 } // namespace
19 25
20 namespace extensions { 26 namespace extensions {
21 27
22 ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context, 28 ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
23 SourceMap* source_map) 29 SourceMap* source_map)
24 : NativeHandler(context->GetIsolate()), 30 : ObjectBackedNativeHandler(context),
25 context_(context),
26 source_map_(source_map), 31 source_map_(source_map),
27 natives_enabled_(0) { 32 natives_enabled_(0) {
28 RouteFunction("require", 33 RouteFunction("require",
29 base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this))); 34 base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this)));
30 RouteFunction("requireNative", 35 RouteFunction("requireNative",
31 base::Bind(&ModuleSystem::GetNative, base::Unretained(this))); 36 base::Bind(&ModuleSystem::RequireNative, base::Unretained(this)));
32 37
33 v8::Handle<v8::Object> global(context_->Global()); 38 v8::Handle<v8::Object> global(context->Global());
34 global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New()); 39 global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New());
35 global->SetHiddenValue(v8::String::New(kModuleSystem), 40 global->SetHiddenValue(v8::String::New(kModuleSystem),
36 v8::External::New(this)); 41 v8::External::New(this));
37 } 42 }
38 43
39 ModuleSystem::~ModuleSystem() { 44 ModuleSystem::~ModuleSystem() {
40 v8::HandleScope handle_scope; 45 Invalidate();
41 // Deleting this value here prevents future lazy field accesses from 46 }
42 // referencing ModuleSystem after it has been freed. 47
43 context_->Global()->DeleteHiddenValue(v8::String::New(kModuleSystem)); 48 void ModuleSystem::Invalidate() {
49 if (!is_valid())
50 return;
51 for (NativeHandlerMap::iterator it = native_handler_map_.begin();
52 it != native_handler_map_.end(); ++it) {
53 it->second->Invalidate();
54 }
55 ObjectBackedNativeHandler::Invalidate();
44 } 56 }
45 57
46 ModuleSystem::NativesEnabledScope::NativesEnabledScope( 58 ModuleSystem::NativesEnabledScope::NativesEnabledScope(
47 ModuleSystem* module_system) 59 ModuleSystem* module_system)
48 : module_system_(module_system) { 60 : module_system_(module_system) {
49 module_system_->natives_enabled_++; 61 module_system_->natives_enabled_++;
50 } 62 }
51 63
52 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { 64 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() {
53 module_system_->natives_enabled_--; 65 module_system_->natives_enabled_--;
54 CHECK_GE(module_system_->natives_enabled_, 0); 66 CHECK_GE(module_system_->natives_enabled_, 0);
55 } 67 }
56 68
57 // static
58 bool ModuleSystem::IsPresentInCurrentContext() {
59 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
60 if (global.IsEmpty())
61 return false;
62 v8::Handle<v8::Value> module_system =
63 global->GetHiddenValue(v8::String::New(kModuleSystem));
64 return !module_system.IsEmpty() && !module_system->IsUndefined();
65 }
66
67 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { 69 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) {
68 DumpException(try_catch); 70 DumpException(try_catch);
69 if (exception_handler_.get()) 71 if (exception_handler_.get())
70 exception_handler_->HandleUncaughtException(); 72 exception_handler_->HandleUncaughtException();
71 } 73 }
72 74
73 // static 75 // static
74 void ModuleSystem::DumpException(const v8::TryCatch& try_catch) { 76 std::string ModuleSystem::CreateExceptionString(const v8::TryCatch& try_catch) {
75 v8::HandleScope handle_scope;
76
77 v8::Handle<v8::Message> message(try_catch.Message()); 77 v8::Handle<v8::Message> message(try_catch.Message());
78 if (message.IsEmpty()) { 78 if (message.IsEmpty()) {
79 LOG(ERROR) << "try_catch has no message"; 79 return "try_catch has no message";
80 return;
81 } 80 }
82 81
83 std::string resource_name = "<unknown resource>"; 82 std::string resource_name = "<unknown resource>";
84 if (!message->GetScriptResourceName().IsEmpty()) { 83 if (!message->GetScriptResourceName().IsEmpty()) {
85 resource_name = 84 resource_name =
86 *v8::String::Utf8Value(message->GetScriptResourceName()->ToString()); 85 *v8::String::Utf8Value(message->GetScriptResourceName()->ToString());
87 } 86 }
88 87
89 std::string error_message = "<no error message>"; 88 std::string error_message = "<no error message>";
90 if (!message->Get().IsEmpty()) 89 if (!message->Get().IsEmpty())
91 error_message = *v8::String::Utf8Value(message->Get()); 90 error_message = *v8::String::Utf8Value(message->Get());
92 91
92 return base::StringPrintf("%s:%d: %s",
93 resource_name.c_str(),
94 message->GetLineNumber(),
95 error_message.c_str());
96 }
97
98 // static
99 void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
100 v8::HandleScope handle_scope;
101
93 std::string stack_trace = "<stack trace unavailable>"; 102 std::string stack_trace = "<stack trace unavailable>";
94 if (!try_catch.StackTrace().IsEmpty()) { 103 if (!try_catch.StackTrace().IsEmpty()) {
95 v8::String::Utf8Value stack_value(try_catch.StackTrace()); 104 v8::String::Utf8Value stack_value(try_catch.StackTrace());
96 if (*stack_value) 105 if (*stack_value)
97 stack_trace.assign(*stack_value, stack_value.length()); 106 stack_trace.assign(*stack_value, stack_value.length());
98 else 107 else
99 stack_trace = "<could not convert stack trace to string>"; 108 stack_trace = "<could not convert stack trace to string>";
100 } 109 }
101 110
102 LOG(ERROR) << "[" << resource_name << "(" << message->GetLineNumber() << ")] " 111 LOG(ERROR) << CreateExceptionString(try_catch) << "{" << stack_trace << "}";
103 << error_message
104 << "{" << stack_trace << "}";
105 } 112 }
106 113
107 void ModuleSystem::Require(const std::string& module_name) { 114 v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) {
108 v8::HandleScope handle_scope; 115 v8::HandleScope handle_scope;
109 RequireForJsInner(v8::String::New(module_name.c_str())); 116 return handle_scope.Close(
117 RequireForJsInner(v8::String::New(module_name.c_str())));
110 } 118 }
111 119
112 v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) { 120 v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
113 v8::HandleScope handle_scope; 121 v8::HandleScope handle_scope;
114 v8::Handle<v8::String> module_name = args[0]->ToString(); 122 v8::Handle<v8::String> module_name = args[0]->ToString();
115 return handle_scope.Close(RequireForJsInner(module_name)); 123 return handle_scope.Close(RequireForJsInner(module_name));
116 } 124 }
117 125
118 v8::Handle<v8::Value> ModuleSystem::RequireForJsInner( 126 v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
119 v8::Handle<v8::String> module_name) { 127 v8::Handle<v8::String> module_name) {
120 v8::HandleScope handle_scope; 128 v8::HandleScope handle_scope;
121 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global()); 129 v8::Handle<v8::Object> global(v8_context()->Global());
122 v8::Handle<v8::Object> modules(v8::Handle<v8::Object>::Cast( 130 v8::Handle<v8::Object> modules(v8::Handle<v8::Object>::Cast(
123 global->GetHiddenValue(v8::String::New(kModulesField)))); 131 global->GetHiddenValue(v8::String::New(kModulesField))));
124 v8::Handle<v8::Value> exports(modules->Get(module_name)); 132 v8::Handle<v8::Value> exports(modules->Get(module_name));
125 if (!exports->IsUndefined()) 133 if (!exports->IsUndefined())
126 return handle_scope.Close(exports); 134 return handle_scope.Close(exports);
127 135
128 v8::Handle<v8::Value> source(GetSource(module_name)); 136 v8::Handle<v8::Value> source(GetSource(module_name));
129 if (source->IsUndefined()) 137 if (source->IsUndefined())
130 return handle_scope.Close(v8::Undefined()); 138 return handle_scope.Close(v8::Undefined());
131 v8::Handle<v8::String> wrapped_source(WrapSource( 139 v8::Handle<v8::String> wrapped_source(WrapSource(
(...skipping 19 matching lines...) Expand all
151 func->Call(global, 3, args); 159 func->Call(global, 3, args);
152 if (try_catch.HasCaught()) { 160 if (try_catch.HasCaught()) {
153 HandleException(try_catch); 161 HandleException(try_catch);
154 return v8::Undefined(); 162 return v8::Undefined();
155 } 163 }
156 } 164 }
157 modules->Set(module_name, exports); 165 modules->Set(module_name, exports);
158 return handle_scope.Close(exports); 166 return handle_scope.Close(exports);
159 } 167 }
160 168
161 void ModuleSystem::CallModuleMethod(const std::string& module_name, 169 v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
162 const std::string& method_name) { 170 const std::string& module_name,
171 const std::string& method_name) {
163 std::vector<v8::Handle<v8::Value> > args; 172 std::vector<v8::Handle<v8::Value> > args;
164 CallModuleMethod(module_name, method_name, &args); 173 return CallModuleMethod(module_name, method_name, &args);
165 } 174 }
166 175
167 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( 176 v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
168 const std::string& module_name, 177 const std::string& module_name,
169 const std::string& method_name, 178 const std::string& method_name,
170 std::vector<v8::Handle<v8::Value> >* args) { 179 std::vector<v8::Handle<v8::Value> >* args) {
171 v8::HandleScope handle_scope; 180 v8::HandleScope handle_scope;
172 v8::Local<v8::Value> module = 181 v8::Local<v8::Value> module =
173 v8::Local<v8::Value>::New( 182 v8::Local<v8::Value>::New(
174 RequireForJsInner(v8::String::New(module_name.c_str()))); 183 RequireForJsInner(v8::String::New(module_name.c_str())));
175 if (module.IsEmpty() || !module->IsObject()) 184 if (module.IsEmpty() || !module->IsObject())
176 return v8::Local<v8::Value>(); 185 return v8::Local<v8::Value>();
177 v8::Local<v8::Value> value = 186 v8::Local<v8::Value> value =
178 v8::Handle<v8::Object>::Cast(module)->Get( 187 v8::Handle<v8::Object>::Cast(module)->Get(
179 v8::String::New(method_name.c_str())); 188 v8::String::New(method_name.c_str()));
180 if (value.IsEmpty() || !value->IsFunction()) 189 if (value.IsEmpty() || !value->IsFunction())
181 return v8::Local<v8::Value>(); 190 return v8::Local<v8::Value>();
182 v8::Handle<v8::Function> func = 191 v8::Handle<v8::Function> func =
183 v8::Handle<v8::Function>::Cast(value); 192 v8::Handle<v8::Function>::Cast(value);
184 // TODO(jeremya/koz): refer to context_ here, not the current context. 193 v8::Handle<v8::Object> global(v8_context()->Global());
185 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
186 v8::Local<v8::Value> result; 194 v8::Local<v8::Value> result;
187 { 195 {
188 WebKit::WebScopedMicrotaskSuppression suppression; 196 WebKit::WebScopedMicrotaskSuppression suppression;
189 v8::TryCatch try_catch; 197 v8::TryCatch try_catch;
190 try_catch.SetCaptureMessage(true); 198 try_catch.SetCaptureMessage(true);
191 result = func->Call(global, args->size(), vector_as_array(args)); 199 result = func->Call(global, args->size(), vector_as_array(args));
192 if (try_catch.HasCaught()) 200 if (try_catch.HasCaught())
193 HandleException(try_catch); 201 HandleException(try_catch);
194 } 202 }
195 return handle_scope.Close(result); 203 return handle_scope.Close(result);
196 } 204 }
197 205
206 bool ModuleSystem::HasNativeHandler(const std::string& name) {
207 return native_handler_map_.find(name) != native_handler_map_.end();
208 }
209
198 void ModuleSystem::RegisterNativeHandler(const std::string& name, 210 void ModuleSystem::RegisterNativeHandler(const std::string& name,
199 scoped_ptr<NativeHandler> native_handler) { 211 scoped_ptr<NativeHandler> native_handler) {
200 native_handler_map_[name] = 212 native_handler_map_[name] =
201 linked_ptr<NativeHandler>(native_handler.release()); 213 linked_ptr<NativeHandler>(native_handler.release());
202 } 214 }
203 215
204 void ModuleSystem::OverrideNativeHandler(const std::string& name) { 216 void ModuleSystem::OverrideNativeHandler(const std::string& name) {
205 overridden_native_handlers_.insert(name); 217 overridden_native_handlers_.insert(name);
206 } 218 }
207 219
208 void ModuleSystem::RunString(const std::string& code, const std::string& name) { 220 void ModuleSystem::RunString(const std::string& code, const std::string& name) {
209 v8::HandleScope handle_scope; 221 v8::HandleScope handle_scope;
210 RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str())); 222 RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str()));
211 } 223 }
212 224
213 // static 225 // static
226 v8::Handle<v8::Value> ModuleSystem::NativeLazyFieldGetter(
227 v8::Local<v8::String> property, const v8::AccessorInfo& info) {
228 return LazyFieldGetterInner(property,
229 info,
230 &ModuleSystem::RequireNativeFromString);
231 }
232
233 // static
214 v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter( 234 v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter(
215 v8::Local<v8::String> property, const v8::AccessorInfo& info) { 235 v8::Local<v8::String> property, const v8::AccessorInfo& info) {
236 return LazyFieldGetterInner(property, info, &ModuleSystem::Require);
237 }
238
239 // static
240 v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner(
241 v8::Local<v8::String> property,
242 const v8::AccessorInfo& info,
243 RequireFunction require_function) {
216 CHECK(!info.Data().IsEmpty()); 244 CHECK(!info.Data().IsEmpty());
217 CHECK(info.Data()->IsObject()); 245 CHECK(info.Data()->IsObject());
218 v8::HandleScope handle_scope; 246 v8::HandleScope handle_scope;
219 v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data()); 247 v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data());
220 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global()); 248 // This context should be the same as v8_context_, but this method is static.
249 v8::Handle<v8::Context> context = parameters->CreationContext();
250 v8::Handle<v8::Object> global(context->Global());
221 v8::Handle<v8::Value> module_system_value = 251 v8::Handle<v8::Value> module_system_value =
222 global->GetHiddenValue(v8::String::New(kModuleSystem)); 252 global->GetHiddenValue(v8::String::New(kModuleSystem));
223 if (module_system_value.IsEmpty() || module_system_value->IsUndefined()) { 253 if (module_system_value.IsEmpty() || module_system_value->IsUndefined()) {
224 // ModuleSystem has been deleted. 254 // ModuleSystem has been deleted.
225 return v8::Undefined(); 255 return v8::Undefined();
226 } 256 }
227 ModuleSystem* module_system = static_cast<ModuleSystem*>( 257 ModuleSystem* module_system = static_cast<ModuleSystem*>(
228 v8::Handle<v8::External>::Cast(module_system_value)->Value()); 258 v8::Handle<v8::External>::Cast(module_system_value)->Value());
229 259
230 v8::Handle<v8::Object> module; 260 std::string name = *v8::String::AsciiValue(
231 { 261 parameters->Get(v8::String::New(kModuleName))->ToString());
232 NativesEnabledScope scope(module_system); 262
233 module = v8::Handle<v8::Object>::Cast(module_system->RequireForJsInner( 263 // Switch to our v8 context because we need functions created while running
234 parameters->Get(v8::String::New(kModuleName))->ToString())); 264 // the require()d module to belong to our context, not the current one.
265 v8::Context::Scope context_scope(context);
266 NativesEnabledScope natives_enabled_scope(module_system);
267
268 v8::TryCatch try_catch;
269 v8::Handle<v8::Object> module = v8::Handle<v8::Object>::Cast(
270 (module_system->*require_function)(name));
271 if (try_catch.HasCaught()) {
272 module_system->HandleException(try_catch);
273 return handle_scope.Close(v8::Handle<v8::Value>());
235 } 274 }
275
236 if (module.IsEmpty()) 276 if (module.IsEmpty())
237 return handle_scope.Close(v8::Handle<v8::Value>()); 277 return handle_scope.Close(v8::Handle<v8::Value>());
238 278
239 v8::Handle<v8::String> field = 279 v8::Handle<v8::String> field =
240 parameters->Get(v8::String::New(kModuleField))->ToString(); 280 parameters->Get(v8::String::New(kModuleField))->ToString();
241 281
242 return handle_scope.Close(module->Get(field)); 282 // http://crbug.com/179741.
283 std::string field_name = *v8::String::AsciiValue(field);
284 char stack_debug[64];
285 base::debug::Alias(&stack_debug);
286 base::snprintf(stack_debug, arraysize(stack_debug),
287 "%s.%s", name.c_str(), field_name.c_str());
288
289 v8::Local<v8::Value> new_field = module->Get(field);
290 v8::Handle<v8::Object> object = info.This();
291 // Delete the getter and set this field to |new_field| so the same object is
292 // returned every time a certain API is accessed.
293 // CHECK is for http://crbug.com/179741.
294 CHECK(!new_field.IsEmpty()) << "Empty require " << name << "." << field_name;
295 if (!new_field->IsUndefined()) {
296 object->Delete(property);
297 object->Set(property, new_field);
298 }
299 return handle_scope.Close(new_field);
243 } 300 }
244 301
245 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object, 302 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
246 const std::string& field, 303 const std::string& field,
247 const std::string& module_name, 304 const std::string& module_name,
248 const std::string& module_field) { 305 const std::string& module_field) {
306 SetLazyField(object, field, module_name, module_field,
307 &ModuleSystem::LazyFieldGetter);
308 }
309
310 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
311 const std::string& field,
312 const std::string& module_name,
313 const std::string& module_field,
314 v8::AccessorGetter getter) {
249 v8::HandleScope handle_scope; 315 v8::HandleScope handle_scope;
250 v8::Handle<v8::Object> parameters = v8::Object::New(); 316 v8::Handle<v8::Object> parameters = v8::Object::New();
251 parameters->Set(v8::String::New(kModuleName), 317 parameters->Set(v8::String::New(kModuleName),
252 v8::String::New(module_name.c_str())); 318 v8::String::New(module_name.c_str()));
253 parameters->Set(v8::String::New(kModuleField), 319 parameters->Set(v8::String::New(kModuleField),
254 v8::String::New(module_field.c_str())); 320 v8::String::New(module_field.c_str()));
255
256 object->SetAccessor(v8::String::New(field.c_str()), 321 object->SetAccessor(v8::String::New(field.c_str()),
257 &ModuleSystem::LazyFieldGetter, 322 getter,
258 NULL, 323 NULL,
259 parameters); 324 parameters);
260 } 325 }
261 326
327 void ModuleSystem::SetNativeLazyField(v8::Handle<v8::Object> object,
328 const std::string& field,
329 const std::string& module_name,
330 const std::string& module_field) {
331 SetLazyField(object, field, module_name, module_field,
332 &ModuleSystem::NativeLazyFieldGetter);
333 }
334
262 v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code, 335 v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code,
263 v8::Handle<v8::String> name) { 336 v8::Handle<v8::String> name) {
264 v8::HandleScope handle_scope; 337 v8::HandleScope handle_scope;
265 WebKit::WebScopedMicrotaskSuppression suppression; 338 WebKit::WebScopedMicrotaskSuppression suppression;
266 v8::Handle<v8::Value> result; 339 v8::Handle<v8::Value> result;
267 v8::TryCatch try_catch; 340 v8::TryCatch try_catch;
268 try_catch.SetCaptureMessage(true); 341 try_catch.SetCaptureMessage(true);
269 v8::Handle<v8::Script> script(v8::Script::New(code, name)); 342 v8::Handle<v8::Script> script(v8::Script::New(code, name));
270 if (try_catch.HasCaught()) { 343 if (try_catch.HasCaught()) {
271 HandleException(try_catch); 344 HandleException(try_catch);
272 return handle_scope.Close(result); 345 return handle_scope.Close(result);
273 } 346 }
274 347
275 result = script->Run(); 348 result = script->Run();
276 if (try_catch.HasCaught()) 349 if (try_catch.HasCaught())
277 HandleException(try_catch); 350 HandleException(try_catch);
278 351
279 return handle_scope.Close(result); 352 return handle_scope.Close(result);
280 } 353 }
281 354
282 v8::Handle<v8::Value> ModuleSystem::GetSource( 355 v8::Handle<v8::Value> ModuleSystem::GetSource(
283 v8::Handle<v8::String> source_name) { 356 v8::Handle<v8::String> source_name) {
284 v8::HandleScope handle_scope; 357 v8::HandleScope handle_scope;
285 std::string module_name = *v8::String::AsciiValue(source_name); 358 std::string module_name = *v8::String::AsciiValue(source_name);
286 if (!source_map_->Contains(module_name)) 359 if (!source_map_->Contains(module_name))
287 return v8::Undefined(); 360 return v8::Undefined();
288 return handle_scope.Close(source_map_->GetSource(module_name)); 361 return handle_scope.Close(source_map_->GetSource(module_name));
289 } 362 }
290 363
291 v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) { 364 v8::Handle<v8::Value> ModuleSystem::RequireNative(const v8::Arguments& args) {
292 CHECK_EQ(1, args.Length()); 365 CHECK_EQ(1, args.Length());
366 std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
367 return RequireNativeFromString(native_name);
368 }
369
370 v8::Handle<v8::Value> ModuleSystem::RequireNativeFromString(
371 const std::string& native_name) {
293 if (natives_enabled_ == 0) 372 if (natives_enabled_ == 0)
294 return ThrowException("Natives disabled"); 373 return ThrowException("Natives disabled");
295 std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
296 if (overridden_native_handlers_.count(native_name) > 0u) 374 if (overridden_native_handlers_.count(native_name) > 0u)
297 return RequireForJs(args); 375 return RequireForJsInner(v8::String::New(native_name.c_str()));
298 NativeHandlerMap::iterator i = native_handler_map_.find(native_name); 376 NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
299 if (i == native_handler_map_.end()) 377 if (i == native_handler_map_.end())
300 return v8::Undefined(); 378 return v8::Undefined();
301 return i->second->NewInstance(); 379 return i->second->NewInstance();
302 } 380 }
303 381
304 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) { 382 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) {
305 v8::HandleScope handle_scope; 383 v8::HandleScope handle_scope;
306 v8::Handle<v8::String> left = v8::String::New( 384 v8::Handle<v8::String> left = v8::String::New(
307 "(function(require, requireNative, exports) {'use strict';"); 385 "(function(require, requireNative, exports) {'use strict';");
308 v8::Handle<v8::String> right = v8::String::New("\n})"); 386 v8::Handle<v8::String> right = v8::String::New("\n})");
309 return handle_scope.Close( 387 return handle_scope.Close(
310 v8::String::Concat(left, v8::String::Concat(source, right))); 388 v8::String::Concat(left, v8::String::Concat(source, right)));
311 } 389 }
312 390
313 v8::Handle<v8::Value> ModuleSystem::ThrowException(const std::string& message) { 391 v8::Handle<v8::Value> ModuleSystem::ThrowException(const std::string& message) {
314 return v8::ThrowException(v8::String::New(message.c_str())); 392 return v8::ThrowException(v8::String::New(message.c_str()));
315 } 393 }
316 394
317 } // extensions 395 } // extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/module_system.h ('k') | chrome/renderer/extensions/module_system_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698