| OLD | NEW |
| 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/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 // Default exception handler which logs the exception. | 67 // Default exception handler which logs the exception. |
| 68 class DefaultExceptionHandler : public ModuleSystem::ExceptionHandler { | 68 class DefaultExceptionHandler : public ModuleSystem::ExceptionHandler { |
| 69 public: | 69 public: |
| 70 explicit DefaultExceptionHandler(ChromeV8Context* context) | 70 explicit DefaultExceptionHandler(ChromeV8Context* context) |
| 71 : context_(context) {} | 71 : context_(context) {} |
| 72 | 72 |
| 73 // Fatally dumps the debug info from |try_catch| to the console. | 73 // Fatally dumps the debug info from |try_catch| to the console. |
| 74 // Make sure this is never used for exceptions that originate in external | 74 // Make sure this is never used for exceptions that originate in external |
| 75 // code! | 75 // code! |
| 76 virtual void HandleUncaughtException(const v8::TryCatch& try_catch) OVERRIDE { | 76 virtual void HandleUncaughtException(const v8::TryCatch& try_catch) OVERRIDE { |
| 77 v8::HandleScope handle_scope; | 77 v8::HandleScope handle_scope(context_->isolate()); |
| 78 std::string stack_trace = "<stack trace unavailable>"; | 78 std::string stack_trace = "<stack trace unavailable>"; |
| 79 if (!try_catch.StackTrace().IsEmpty()) { | 79 if (!try_catch.StackTrace().IsEmpty()) { |
| 80 v8::String::Utf8Value stack_value(try_catch.StackTrace()); | 80 v8::String::Utf8Value stack_value(try_catch.StackTrace()); |
| 81 if (*stack_value) | 81 if (*stack_value) |
| 82 stack_trace.assign(*stack_value, stack_value.length()); | 82 stack_trace.assign(*stack_value, stack_value.length()); |
| 83 else | 83 else |
| 84 stack_trace = "<could not convert stack trace to string>"; | 84 stack_trace = "<could not convert stack trace to string>"; |
| 85 } | 85 } |
| 86 Fatal(context_, CreateExceptionString(try_catch) + "{" + stack_trace + "}"); | 86 Fatal(context_, CreateExceptionString(try_catch) + "{" + stack_trace + "}"); |
| 87 } | 87 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 Invalidate(); | 139 Invalidate(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void ModuleSystem::Invalidate() { | 142 void ModuleSystem::Invalidate() { |
| 143 if (!is_valid()) | 143 if (!is_valid()) |
| 144 return; | 144 return; |
| 145 | 145 |
| 146 // Clear the module system properties from the global context. It's polite, | 146 // Clear the module system properties from the global context. It's polite, |
| 147 // and we use this as a signal in lazy handlers that we no longer exist. | 147 // and we use this as a signal in lazy handlers that we no longer exist. |
| 148 { | 148 { |
| 149 v8::HandleScope scope; | 149 v8::HandleScope scope(GetIsolate()); |
| 150 v8::Handle<v8::Object> global = context()->v8_context()->Global(); | 150 v8::Handle<v8::Object> global = context()->v8_context()->Global(); |
| 151 global->DeleteHiddenValue(v8::String::New(kModulesField)); | 151 global->DeleteHiddenValue(v8::String::New(kModulesField)); |
| 152 global->DeleteHiddenValue(v8::String::New(kModuleSystem)); | 152 global->DeleteHiddenValue(v8::String::New(kModuleSystem)); |
| 153 } | 153 } |
| 154 | 154 |
| 155 // Invalidate all of the successfully required handlers we own. | 155 // Invalidate all of the successfully required handlers we own. |
| 156 for (NativeHandlerMap::iterator it = native_handler_map_.begin(); | 156 for (NativeHandlerMap::iterator it = native_handler_map_.begin(); |
| 157 it != native_handler_map_.end(); ++it) { | 157 it != native_handler_map_.end(); ++it) { |
| 158 it->second->Invalidate(); | 158 it->second->Invalidate(); |
| 159 } | 159 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 170 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { | 170 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { |
| 171 module_system_->natives_enabled_--; | 171 module_system_->natives_enabled_--; |
| 172 CHECK_GE(module_system_->natives_enabled_, 0); | 172 CHECK_GE(module_system_->natives_enabled_, 0); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { | 175 void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { |
| 176 exception_handler_->HandleUncaughtException(try_catch); | 176 exception_handler_->HandleUncaughtException(try_catch); |
| 177 } | 177 } |
| 178 | 178 |
| 179 v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) { | 179 v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) { |
| 180 v8::HandleScope handle_scope; | 180 v8::HandleScope handle_scope(GetIsolate()); |
| 181 return handle_scope.Close( | 181 return handle_scope.Close( |
| 182 RequireForJsInner(v8::String::New(module_name.c_str()))); | 182 RequireForJsInner(v8::String::New(module_name.c_str()))); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void ModuleSystem::RequireForJs( | 185 void ModuleSystem::RequireForJs( |
| 186 const v8::FunctionCallbackInfo<v8::Value>& args) { | 186 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 187 v8::Handle<v8::String> module_name = args[0]->ToString(); | 187 v8::Handle<v8::String> module_name = args[0]->ToString(); |
| 188 args.GetReturnValue().Set(RequireForJsInner(module_name)); | 188 args.GetReturnValue().Set(RequireForJsInner(module_name)); |
| 189 } | 189 } |
| 190 | 190 |
| 191 v8::Handle<v8::Value> ModuleSystem::RequireForJsInner( | 191 v8::Handle<v8::Value> ModuleSystem::RequireForJsInner( |
| 192 v8::Handle<v8::String> module_name) { | 192 v8::Handle<v8::String> module_name) { |
| 193 v8::HandleScope handle_scope; | 193 v8::HandleScope handle_scope(GetIsolate()); |
| 194 v8::Context::Scope context_scope(context()->v8_context()); | 194 v8::Context::Scope context_scope(context()->v8_context()); |
| 195 | 195 |
| 196 v8::Handle<v8::Object> global(context()->v8_context()->Global()); | 196 v8::Handle<v8::Object> global(context()->v8_context()->Global()); |
| 197 | 197 |
| 198 // The module system might have been deleted. This can happen if a different | 198 // The module system might have been deleted. This can happen if a different |
| 199 // context keeps a reference to us, but our frame is destroyed (e.g. | 199 // context keeps a reference to us, but our frame is destroyed (e.g. |
| 200 // background page keeps reference to chrome object in a closed popup). | 200 // background page keeps reference to chrome object in a closed popup). |
| 201 v8::Handle<v8::Value> modules_value = | 201 v8::Handle<v8::Value> modules_value = |
| 202 global->GetHiddenValue(v8::String::New(kModulesField)); | 202 global->GetHiddenValue(v8::String::New(kModulesField)); |
| 203 if (modules_value.IsEmpty() || modules_value->IsUndefined()) { | 203 if (modules_value.IsEmpty() || modules_value->IsUndefined()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 return v8::Undefined(); | 256 return v8::Undefined(); |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 modules->Set(module_name, exports); | 259 modules->Set(module_name, exports); |
| 260 return handle_scope.Close(exports); | 260 return handle_scope.Close(exports); |
| 261 } | 261 } |
| 262 | 262 |
| 263 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( | 263 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( |
| 264 const std::string& module_name, | 264 const std::string& module_name, |
| 265 const std::string& method_name) { | 265 const std::string& method_name) { |
| 266 v8::HandleScope handle_scope; | 266 v8::HandleScope handle_scope(GetIsolate()); |
| 267 v8::Handle<v8::Value> no_args; | 267 v8::Handle<v8::Value> no_args; |
| 268 return CallModuleMethod(module_name, method_name, 0, &no_args); | 268 return CallModuleMethod(module_name, method_name, 0, &no_args); |
| 269 } | 269 } |
| 270 | 270 |
| 271 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( | 271 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( |
| 272 const std::string& module_name, | 272 const std::string& module_name, |
| 273 const std::string& method_name, | 273 const std::string& method_name, |
| 274 std::vector<v8::Handle<v8::Value> >* args) { | 274 std::vector<v8::Handle<v8::Value> >* args) { |
| 275 return CallModuleMethod( | 275 return CallModuleMethod( |
| 276 module_name, method_name, args->size(), vector_as_array(args)); | 276 module_name, method_name, args->size(), vector_as_array(args)); |
| 277 } | 277 } |
| 278 | 278 |
| 279 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( | 279 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( |
| 280 const std::string& module_name, | 280 const std::string& module_name, |
| 281 const std::string& method_name, | 281 const std::string& method_name, |
| 282 int argc, | 282 int argc, |
| 283 v8::Handle<v8::Value> argv[]) { | 283 v8::Handle<v8::Value> argv[]) { |
| 284 TRACE_EVENT2("v8", "v8.callModuleMethod", | 284 TRACE_EVENT2("v8", "v8.callModuleMethod", |
| 285 "module_name", module_name, | 285 "module_name", module_name, |
| 286 "method_name", method_name); | 286 "method_name", method_name); |
| 287 | 287 |
| 288 v8::HandleScope handle_scope; | 288 v8::HandleScope handle_scope(GetIsolate()); |
| 289 v8::Context::Scope context_scope(context()->v8_context()); | 289 v8::Context::Scope context_scope(context()->v8_context()); |
| 290 | 290 |
| 291 v8::Local<v8::Value> module; | 291 v8::Local<v8::Value> module; |
| 292 { | 292 { |
| 293 NativesEnabledScope natives_enabled(this); | 293 NativesEnabledScope natives_enabled(this); |
| 294 module = v8::Local<v8::Value>::New( | 294 module = v8::Local<v8::Value>::New( |
| 295 RequireForJsInner(v8::String::New(module_name.c_str()))); | 295 RequireForJsInner(v8::String::New(module_name.c_str()))); |
| 296 } | 296 } |
| 297 | 297 |
| 298 if (module.IsEmpty() || !module->IsObject()) { | 298 if (module.IsEmpty() || !module->IsObject()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 325 scoped_ptr<NativeHandler> native_handler) { | 325 scoped_ptr<NativeHandler> native_handler) { |
| 326 native_handler_map_[name] = | 326 native_handler_map_[name] = |
| 327 linked_ptr<NativeHandler>(native_handler.release()); | 327 linked_ptr<NativeHandler>(native_handler.release()); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void ModuleSystem::OverrideNativeHandlerForTest(const std::string& name) { | 330 void ModuleSystem::OverrideNativeHandlerForTest(const std::string& name) { |
| 331 overridden_native_handlers_.insert(name); | 331 overridden_native_handlers_.insert(name); |
| 332 } | 332 } |
| 333 | 333 |
| 334 void ModuleSystem::RunString(const std::string& code, const std::string& name) { | 334 void ModuleSystem::RunString(const std::string& code, const std::string& name) { |
| 335 v8::HandleScope handle_scope; | 335 v8::HandleScope handle_scope(GetIsolate()); |
| 336 RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str())); | 336 RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str())); |
| 337 } | 337 } |
| 338 | 338 |
| 339 // static | 339 // static |
| 340 void ModuleSystem::NativeLazyFieldGetter( | 340 void ModuleSystem::NativeLazyFieldGetter( |
| 341 v8::Local<v8::String> property, | 341 v8::Local<v8::String> property, |
| 342 const v8::PropertyCallbackInfo<v8::Value>& info) { | 342 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 343 LazyFieldGetterInner(property, | 343 LazyFieldGetterInner(property, |
| 344 info, | 344 info, |
| 345 &ModuleSystem::RequireNativeFromString); | 345 &ModuleSystem::RequireNativeFromString); |
| 346 } | 346 } |
| 347 | 347 |
| 348 // static | 348 // static |
| 349 void ModuleSystem::LazyFieldGetter( | 349 void ModuleSystem::LazyFieldGetter( |
| 350 v8::Local<v8::String> property, | 350 v8::Local<v8::String> property, |
| 351 const v8::PropertyCallbackInfo<v8::Value>& info) { | 351 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 352 LazyFieldGetterInner(property, info, &ModuleSystem::Require); | 352 LazyFieldGetterInner(property, info, &ModuleSystem::Require); |
| 353 } | 353 } |
| 354 | 354 |
| 355 // static | 355 // static |
| 356 void ModuleSystem::LazyFieldGetterInner( | 356 void ModuleSystem::LazyFieldGetterInner( |
| 357 v8::Local<v8::String> property, | 357 v8::Local<v8::String> property, |
| 358 const v8::PropertyCallbackInfo<v8::Value>& info, | 358 const v8::PropertyCallbackInfo<v8::Value>& info, |
| 359 RequireFunction require_function) { | 359 RequireFunction require_function) { |
| 360 CHECK(!info.Data().IsEmpty()); | 360 CHECK(!info.Data().IsEmpty()); |
| 361 CHECK(info.Data()->IsObject()); | 361 CHECK(info.Data()->IsObject()); |
| 362 v8::HandleScope handle_scope; | 362 v8::HandleScope handle_scope(info.GetIsolate()); |
| 363 v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data()); | 363 v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data()); |
| 364 // This context should be the same as context()->v8_context(). | 364 // This context should be the same as context()->v8_context(). |
| 365 v8::Handle<v8::Context> context = parameters->CreationContext(); | 365 v8::Handle<v8::Context> context = parameters->CreationContext(); |
| 366 v8::Handle<v8::Object> global(context->Global()); | 366 v8::Handle<v8::Object> global(context->Global()); |
| 367 v8::Handle<v8::Value> module_system_value = | 367 v8::Handle<v8::Value> module_system_value = |
| 368 global->GetHiddenValue(v8::String::New(kModuleSystem)); | 368 global->GetHiddenValue(v8::String::New(kModuleSystem)); |
| 369 if (module_system_value.IsEmpty() || !module_system_value->IsExternal()) { | 369 if (module_system_value.IsEmpty() || !module_system_value->IsExternal()) { |
| 370 // ModuleSystem has been deleted. | 370 // ModuleSystem has been deleted. |
| 371 // TODO(kalman): See comment in header file. | 371 // TODO(kalman): See comment in header file. |
| 372 Warn("Module system has been deleted, does extension view exist?"); | 372 Warn("Module system has been deleted, does extension view exist?"); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 const std::string& module_field) { | 431 const std::string& module_field) { |
| 432 SetLazyField(object, field, module_name, module_field, | 432 SetLazyField(object, field, module_name, module_field, |
| 433 &ModuleSystem::LazyFieldGetter); | 433 &ModuleSystem::LazyFieldGetter); |
| 434 } | 434 } |
| 435 | 435 |
| 436 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object, | 436 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object, |
| 437 const std::string& field, | 437 const std::string& field, |
| 438 const std::string& module_name, | 438 const std::string& module_name, |
| 439 const std::string& module_field, | 439 const std::string& module_field, |
| 440 v8::AccessorGetterCallback getter) { | 440 v8::AccessorGetterCallback getter) { |
| 441 v8::HandleScope handle_scope; | 441 v8::HandleScope handle_scope(GetIsolate()); |
| 442 v8::Handle<v8::Object> parameters = v8::Object::New(); | 442 v8::Handle<v8::Object> parameters = v8::Object::New(); |
| 443 parameters->Set(v8::String::New(kModuleName), | 443 parameters->Set(v8::String::New(kModuleName), |
| 444 v8::String::New(module_name.c_str())); | 444 v8::String::New(module_name.c_str())); |
| 445 parameters->Set(v8::String::New(kModuleField), | 445 parameters->Set(v8::String::New(kModuleField), |
| 446 v8::String::New(module_field.c_str())); | 446 v8::String::New(module_field.c_str())); |
| 447 object->SetAccessor(v8::String::New(field.c_str()), | 447 object->SetAccessor(v8::String::New(field.c_str()), |
| 448 getter, | 448 getter, |
| 449 NULL, | 449 NULL, |
| 450 parameters); | 450 parameters); |
| 451 } | 451 } |
| 452 | 452 |
| 453 void ModuleSystem::SetNativeLazyField(v8::Handle<v8::Object> object, | 453 void ModuleSystem::SetNativeLazyField(v8::Handle<v8::Object> object, |
| 454 const std::string& field, | 454 const std::string& field, |
| 455 const std::string& module_name, | 455 const std::string& module_name, |
| 456 const std::string& module_field) { | 456 const std::string& module_field) { |
| 457 SetLazyField(object, field, module_name, module_field, | 457 SetLazyField(object, field, module_name, module_field, |
| 458 &ModuleSystem::NativeLazyFieldGetter); | 458 &ModuleSystem::NativeLazyFieldGetter); |
| 459 } | 459 } |
| 460 | 460 |
| 461 |
| 462 v8::Isolate* ModuleSystem::GetIsolate() const { |
| 463 return context_->isolate(); |
| 464 } |
| 465 |
| 461 v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code, | 466 v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code, |
| 462 v8::Handle<v8::String> name) { | 467 v8::Handle<v8::String> name) { |
| 463 v8::HandleScope handle_scope; | 468 v8::HandleScope handle_scope(GetIsolate()); |
| 464 v8::Context::Scope context_scope(context()->v8_context()); | 469 v8::Context::Scope context_scope(context()->v8_context()); |
| 465 | 470 |
| 466 WebKit::WebScopedMicrotaskSuppression suppression; | 471 WebKit::WebScopedMicrotaskSuppression suppression; |
| 467 v8::TryCatch try_catch; | 472 v8::TryCatch try_catch; |
| 468 try_catch.SetCaptureMessage(true); | 473 try_catch.SetCaptureMessage(true); |
| 469 v8::Handle<v8::Script> script(v8::Script::New(code, name)); | 474 v8::Handle<v8::Script> script(v8::Script::New(code, name)); |
| 470 if (try_catch.HasCaught()) { | 475 if (try_catch.HasCaught()) { |
| 471 HandleException(try_catch); | 476 HandleException(try_catch); |
| 472 return v8::Undefined(); | 477 return v8::Undefined(); |
| 473 } | 478 } |
| 474 | 479 |
| 475 v8::Handle<v8::Value> result = script->Run(); | 480 v8::Handle<v8::Value> result = script->Run(); |
| 476 if (try_catch.HasCaught()) { | 481 if (try_catch.HasCaught()) { |
| 477 HandleException(try_catch); | 482 HandleException(try_catch); |
| 478 return v8::Undefined(); | 483 return v8::Undefined(); |
| 479 } | 484 } |
| 480 | 485 |
| 481 return handle_scope.Close(result); | 486 return handle_scope.Close(result); |
| 482 } | 487 } |
| 483 | 488 |
| 484 v8::Handle<v8::Value> ModuleSystem::GetSource(const std::string& module_name) { | 489 v8::Handle<v8::Value> ModuleSystem::GetSource(const std::string& module_name) { |
| 485 v8::HandleScope handle_scope; | 490 v8::HandleScope handle_scope(GetIsolate()); |
| 486 if (!source_map_->Contains(module_name)) | 491 if (!source_map_->Contains(module_name)) |
| 487 return v8::Undefined(); | 492 return v8::Undefined(); |
| 488 return handle_scope.Close(source_map_->GetSource(module_name)); | 493 return handle_scope.Close(source_map_->GetSource(module_name)); |
| 489 } | 494 } |
| 490 | 495 |
| 491 void ModuleSystem::RequireNative( | 496 void ModuleSystem::RequireNative( |
| 492 const v8::FunctionCallbackInfo<v8::Value>& args) { | 497 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 493 CHECK_EQ(1, args.Length()); | 498 CHECK_EQ(1, args.Length()); |
| 494 std::string native_name = *v8::String::AsciiValue(args[0]->ToString()); | 499 std::string native_name = *v8::String::AsciiValue(args[0]->ToString()); |
| 495 args.GetReturnValue().Set(RequireNativeFromString(native_name)); | 500 args.GetReturnValue().Set(RequireNativeFromString(native_name)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 513 NativeHandlerMap::iterator i = native_handler_map_.find(native_name); | 518 NativeHandlerMap::iterator i = native_handler_map_.find(native_name); |
| 514 if (i == native_handler_map_.end()) { | 519 if (i == native_handler_map_.end()) { |
| 515 Fatal(context_, | 520 Fatal(context_, |
| 516 "Couldn't find native for requireNative(" + native_name + ")"); | 521 "Couldn't find native for requireNative(" + native_name + ")"); |
| 517 return v8::Undefined(); | 522 return v8::Undefined(); |
| 518 } | 523 } |
| 519 return i->second->NewInstance(); | 524 return i->second->NewInstance(); |
| 520 } | 525 } |
| 521 | 526 |
| 522 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) { | 527 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) { |
| 523 v8::HandleScope handle_scope; | 528 v8::HandleScope handle_scope(GetIsolate()); |
| 524 // Keep in order with the arguments in RequireForJsInner. | 529 // Keep in order with the arguments in RequireForJsInner. |
| 525 v8::Handle<v8::String> left = v8::String::New( | 530 v8::Handle<v8::String> left = v8::String::New( |
| 526 "(function(require, requireNative, exports, " | 531 "(function(require, requireNative, exports, " |
| 527 "console, " | 532 "console, " |
| 528 "$Array, $Function, $JSON, $Object, $RegExp, $String) {" | 533 "$Array, $Function, $JSON, $Object, $RegExp, $String) {" |
| 529 "'use strict';"); | 534 "'use strict';"); |
| 530 v8::Handle<v8::String> right = v8::String::New("\n})"); | 535 v8::Handle<v8::String> right = v8::String::New("\n})"); |
| 531 return handle_scope.Close( | 536 return handle_scope.Close( |
| 532 v8::String::Concat(left, v8::String::Concat(source, right))); | 537 v8::String::Concat(left, v8::String::Concat(source, right))); |
| 533 } | 538 } |
| 534 | 539 |
| 535 } // namespace extensions | 540 } // namespace extensions |
| OLD | NEW |