OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "extensions/renderer/module_system.h" | 5 #include "extensions/renderer/module_system.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 189 |
190 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { | 190 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { |
191 module_system_->natives_enabled_--; | 191 module_system_->natives_enabled_--; |
192 CHECK_GE(module_system_->natives_enabled_, 0); | 192 CHECK_GE(module_system_->natives_enabled_, 0); |
193 } | 193 } |
194 | 194 |
195 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { | 195 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { |
196 exception_handler_->HandleUncaughtException(try_catch); | 196 exception_handler_->HandleUncaughtException(try_catch); |
197 } | 197 } |
198 | 198 |
199 v8::Local<v8::Value> ModuleSystem::Require(const std::string& module_name) { | 199 v8::MaybeLocal<v8::Object> ModuleSystem::Require( |
200 if (module_name.size() >= v8::String::kMaxLength) | 200 const std::string& module_name) { |
201 return v8::Undefined(GetIsolate()); | 201 v8::Local<v8::String> v8_module_name; |
| 202 if (!ToV8String(GetIsolate(), module_name, &v8_module_name)) |
| 203 return v8::MaybeLocal<v8::Object>(); |
202 v8::EscapableHandleScope handle_scope(GetIsolate()); | 204 v8::EscapableHandleScope handle_scope(GetIsolate()); |
203 return handle_scope.Escape(RequireForJsInner( | 205 v8::Local<v8::Value> value = RequireForJsInner( |
204 ToV8StringUnsafe(GetIsolate(), module_name.c_str()))); | 206 v8_module_name); |
| 207 if (value.IsEmpty() || !value->IsObject()) |
| 208 return v8::MaybeLocal<v8::Object>(); |
| 209 return handle_scope.Escape(value.As<v8::Object>()); |
205 } | 210 } |
206 | 211 |
207 void ModuleSystem::RequireForJs( | 212 void ModuleSystem::RequireForJs( |
208 const v8::FunctionCallbackInfo<v8::Value>& args) { | 213 const v8::FunctionCallbackInfo<v8::Value>& args) { |
209 if (!args[0]->IsString()) { | 214 if (!args[0]->IsString()) { |
210 NOTREACHED() << "require() called with a non-string argument"; | 215 NOTREACHED() << "require() called with a non-string argument"; |
211 return; | 216 return; |
212 } | 217 } |
213 v8::Local<v8::String> module_name = args[0].As<v8::String>(); | 218 v8::Local<v8::String> module_name = args[0].As<v8::String>(); |
214 args.GetReturnValue().Set(RequireForJsInner(module_name)); | 219 args.GetReturnValue().Set(RequireForJsInner(module_name)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 return; | 393 return; |
389 } | 394 } |
390 std::string name = *v8::String::Utf8Value(v8_module_name); | 395 std::string name = *v8::String::Utf8Value(v8_module_name); |
391 | 396 |
392 // Switch to our v8 context because we need functions created while running | 397 // Switch to our v8 context because we need functions created while running |
393 // the require()d module to belong to our context, not the current one. | 398 // the require()d module to belong to our context, not the current one. |
394 v8::Context::Scope context_scope(context); | 399 v8::Context::Scope context_scope(context); |
395 NativesEnabledScope natives_enabled_scope(module_system); | 400 NativesEnabledScope natives_enabled_scope(module_system); |
396 | 401 |
397 v8::TryCatch try_catch(info.GetIsolate()); | 402 v8::TryCatch try_catch(info.GetIsolate()); |
398 v8::Local<v8::Value> module_value = (module_system->*require_function)(name); | 403 v8::Local<v8::Value> module_value; |
399 if (try_catch.HasCaught()) { | 404 if (!(module_system->*require_function)(name).ToLocal(&module_value)) { |
400 module_system->HandleException(try_catch); | 405 module_system->HandleException(try_catch); |
401 return; | 406 return; |
402 } | 407 } |
403 if (module_value.IsEmpty() || !module_value->IsObject()) { | |
404 // require_function will have already logged this, we don't need to. | |
405 return; | |
406 } | |
407 | 408 |
408 v8::Local<v8::Object> module = v8::Local<v8::Object>::Cast(module_value); | 409 v8::Local<v8::Object> module = v8::Local<v8::Object>::Cast(module_value); |
409 v8::Local<v8::Value> field_value; | 410 v8::Local<v8::Value> field_value; |
410 if (!GetProperty(context, parameters, kModuleField, &field_value)) { | 411 if (!GetProperty(context, parameters, kModuleField, &field_value)) { |
411 module_system->HandleException(try_catch); | 412 module_system->HandleException(try_catch); |
412 return; | 413 return; |
413 } | 414 } |
414 v8::Local<v8::String> field; | 415 v8::Local<v8::String> field; |
415 if (!field_value->ToString(context).ToLocal(&field)) { | 416 if (!field_value->ToString(context).ToLocal(&field)) { |
416 module_system->HandleException(try_catch); | 417 module_system->HandleException(try_catch); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 if (!source_map_->Contains(module_name)) | 530 if (!source_map_->Contains(module_name)) |
530 return v8::Undefined(GetIsolate()); | 531 return v8::Undefined(GetIsolate()); |
531 return handle_scope.Escape( | 532 return handle_scope.Escape( |
532 v8::Local<v8::Value>(source_map_->GetSource(GetIsolate(), module_name))); | 533 v8::Local<v8::Value>(source_map_->GetSource(GetIsolate(), module_name))); |
533 } | 534 } |
534 | 535 |
535 void ModuleSystem::RequireNative( | 536 void ModuleSystem::RequireNative( |
536 const v8::FunctionCallbackInfo<v8::Value>& args) { | 537 const v8::FunctionCallbackInfo<v8::Value>& args) { |
537 CHECK_EQ(1, args.Length()); | 538 CHECK_EQ(1, args.Length()); |
538 std::string native_name = *v8::String::Utf8Value(args[0]); | 539 std::string native_name = *v8::String::Utf8Value(args[0]); |
539 args.GetReturnValue().Set(RequireNativeFromString(native_name)); | 540 v8::Local<v8::Object> object; |
| 541 if (RequireNativeFromString(native_name).ToLocal(&object)) |
| 542 args.GetReturnValue().Set(object); |
540 } | 543 } |
541 | 544 |
542 v8::Local<v8::Value> ModuleSystem::RequireNativeFromString( | 545 v8::MaybeLocal<v8::Object> ModuleSystem::RequireNativeFromString( |
543 const std::string& native_name) { | 546 const std::string& native_name) { |
544 if (natives_enabled_ == 0) { | 547 if (natives_enabled_ == 0) { |
545 // HACK: if in test throw exception so that we can test the natives-disabled | 548 // HACK: if in test throw exception so that we can test the natives-disabled |
546 // logic; however, under normal circumstances, this is programmer error so | 549 // logic; however, under normal circumstances, this is programmer error so |
547 // we could crash. | 550 // we could crash. |
548 if (exception_handler_) { | 551 if (exception_handler_) { |
549 return GetIsolate()->ThrowException( | 552 GetIsolate()->ThrowException( |
550 ToV8StringUnsafe(GetIsolate(), "Natives disabled")); | 553 ToV8StringUnsafe(GetIsolate(), "Natives disabled")); |
| 554 return v8::MaybeLocal<v8::Object>(); |
551 } | 555 } |
552 Fatal(context_, "Natives disabled for requireNative(" + native_name + ")"); | 556 Fatal(context_, "Natives disabled for requireNative(" + native_name + ")"); |
553 return v8::Undefined(GetIsolate()); | 557 return v8::MaybeLocal<v8::Object>(); |
554 } | 558 } |
555 | 559 |
556 if (overridden_native_handlers_.count(native_name) > 0u) { | 560 if (overridden_native_handlers_.count(native_name) > 0u) { |
557 return RequireForJsInner( | 561 v8::Local<v8::Value> value = RequireForJsInner( |
558 ToV8StringUnsafe(GetIsolate(), native_name.c_str())); | 562 ToV8StringUnsafe(GetIsolate(), native_name.c_str())); |
| 563 if (value.IsEmpty() || !value->IsObject()) |
| 564 return v8::MaybeLocal<v8::Object>(); |
| 565 return value.As<v8::Object>(); |
559 } | 566 } |
560 | 567 |
561 NativeHandlerMap::iterator i = native_handler_map_.find(native_name); | 568 NativeHandlerMap::iterator i = native_handler_map_.find(native_name); |
562 if (i == native_handler_map_.end()) { | 569 if (i == native_handler_map_.end()) { |
563 Fatal(context_, | 570 Fatal(context_, |
564 "Couldn't find native for requireNative(" + native_name + ")"); | 571 "Couldn't find native for requireNative(" + native_name + ")"); |
565 return v8::Undefined(GetIsolate()); | 572 return v8::MaybeLocal<v8::Object>(); |
566 } | 573 } |
567 return i->second->NewInstance(); | 574 return i->second->NewInstance(); |
568 } | 575 } |
569 | 576 |
570 void ModuleSystem::RequireAsync( | 577 void ModuleSystem::RequireAsync( |
571 const v8::FunctionCallbackInfo<v8::Value>& args) { | 578 const v8::FunctionCallbackInfo<v8::Value>& args) { |
572 CHECK_EQ(1, args.Length()); | 579 CHECK_EQ(1, args.Length()); |
573 std::string module_name = *v8::String::Utf8Value(args[0]); | 580 std::string module_name = *v8::String::Utf8Value(args[0]); |
574 v8::Local<v8::Context> v8_context = context_->v8_context(); | 581 v8::Local<v8::Context> v8_context = context_->v8_context(); |
575 v8::Local<v8::Promise::Resolver> resolver( | 582 v8::Local<v8::Promise::Resolver> resolver( |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 | 746 |
740 void ModuleSystem::ClobberExistingNativeHandler(const std::string& name) { | 747 void ModuleSystem::ClobberExistingNativeHandler(const std::string& name) { |
741 NativeHandlerMap::iterator existing_handler = native_handler_map_.find(name); | 748 NativeHandlerMap::iterator existing_handler = native_handler_map_.find(name); |
742 if (existing_handler != native_handler_map_.end()) { | 749 if (existing_handler != native_handler_map_.end()) { |
743 clobbered_native_handlers_.push_back(existing_handler->second); | 750 clobbered_native_handlers_.push_back(existing_handler->second); |
744 native_handler_map_.erase(existing_handler); | 751 native_handler_map_.erase(existing_handler); |
745 } | 752 } |
746 } | 753 } |
747 | 754 |
748 } // namespace extensions | 755 } // namespace extensions |
OLD | NEW |