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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp

Issue 1483733002: Remove support for NPObjects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 12 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
3 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2014 Opera Software ASA. All rights reserved. 4 * Copyright (C) 2014 Opera Software ASA. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
(...skipping 15 matching lines...) Expand all
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33 #include "bindings/core/v8/ScriptController.h" 33 #include "bindings/core/v8/ScriptController.h"
34 34
35 #include "bindings/core/v8/BindingSecurity.h" 35 #include "bindings/core/v8/BindingSecurity.h"
36 #include "bindings/core/v8/NPV8Object.h"
37 #include "bindings/core/v8/ScriptCallStackFactory.h" 36 #include "bindings/core/v8/ScriptCallStackFactory.h"
38 #include "bindings/core/v8/ScriptSourceCode.h" 37 #include "bindings/core/v8/ScriptSourceCode.h"
39 #include "bindings/core/v8/ScriptValue.h" 38 #include "bindings/core/v8/ScriptValue.h"
40 #include "bindings/core/v8/V8Binding.h" 39 #include "bindings/core/v8/V8Binding.h"
41 #include "bindings/core/v8/V8Event.h" 40 #include "bindings/core/v8/V8Event.h"
42 #include "bindings/core/v8/V8GCController.h" 41 #include "bindings/core/v8/V8GCController.h"
43 #include "bindings/core/v8/V8HTMLElement.h" 42 #include "bindings/core/v8/V8HTMLElement.h"
44 #include "bindings/core/v8/V8NPObject.h"
45 #include "bindings/core/v8/V8PerContextData.h" 43 #include "bindings/core/v8/V8PerContextData.h"
46 #include "bindings/core/v8/V8ScriptRunner.h" 44 #include "bindings/core/v8/V8ScriptRunner.h"
47 #include "bindings/core/v8/V8Window.h" 45 #include "bindings/core/v8/V8Window.h"
48 #include "bindings/core/v8/WindowProxy.h" 46 #include "bindings/core/v8/WindowProxy.h"
49 #include "bindings/core/v8/npruntime_impl.h"
50 #include "bindings/core/v8/npruntime_priv.h"
51 #include "core/dom/Document.h" 47 #include "core/dom/Document.h"
52 #include "core/dom/Node.h" 48 #include "core/dom/Node.h"
53 #include "core/dom/ScriptableDocumentParser.h" 49 #include "core/dom/ScriptableDocumentParser.h"
54 #include "core/events/Event.h" 50 #include "core/events/Event.h"
55 #include "core/events/EventListener.h" 51 #include "core/events/EventListener.h"
56 #include "core/frame/LocalDOMWindow.h" 52 #include "core/frame/LocalDOMWindow.h"
57 #include "core/frame/Settings.h" 53 #include "core/frame/Settings.h"
58 #include "core/frame/UseCounter.h" 54 #include "core/frame/UseCounter.h"
59 #include "core/frame/csp/ContentSecurityPolicy.h" 55 #include "core/frame/csp/ContentSecurityPolicy.h"
60 #include "core/html/HTMLPlugInElement.h" 56 #include "core/html/HTMLPlugInElement.h"
(...skipping 26 matching lines...) Expand all
87 { 83 {
88 if (!frame) 84 if (!frame)
89 return false; 85 return false;
90 v8::Isolate* isolate = toIsolate(frame); 86 v8::Isolate* isolate = toIsolate(frame);
91 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError); 87 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError);
92 } 88 }
93 89
94 ScriptController::ScriptController(LocalFrame* frame) 90 ScriptController::ScriptController(LocalFrame* frame)
95 : m_windowProxyManager(WindowProxyManager::create(*frame)) 91 : m_windowProxyManager(WindowProxyManager::create(*frame))
96 , m_sourceURL(0) 92 , m_sourceURL(0)
97 , m_windowScriptNPObject(0)
98 { 93 {
99 } 94 }
100 95
101 ScriptController::~ScriptController() 96 ScriptController::~ScriptController()
102 { 97 {
103 } 98 }
104 99
105 DEFINE_TRACE(ScriptController) 100 DEFINE_TRACE(ScriptController)
106 { 101 {
107 #if ENABLE(OILPAN) 102 #if ENABLE(OILPAN)
108 visitor->trace(m_windowProxyManager); 103 visitor->trace(m_windowProxyManager);
109 visitor->trace(m_pluginObjects);
110 #endif 104 #endif
111 } 105 }
112 106
113 void ScriptController::clearScriptObjects()
114 {
115 PluginObjectMap::iterator it = m_pluginObjects.begin();
116 for (; it != m_pluginObjects.end(); ++it) {
117 _NPN_UnregisterObject(it->value);
118 _NPN_ReleaseObject(it->value);
119 }
120 m_pluginObjects.clear();
121
122 if (m_windowScriptNPObject) {
123 // Dispose of the underlying V8 object before releasing our reference
124 // to it, so that if a plugin fails to release it properly we will
125 // only leak the NPObject wrapper, not the object, its document, or
126 // anything else they reference.
127 disposeUnderlyingV8Object(isolate(), m_windowScriptNPObject);
128 _NPN_ReleaseObject(m_windowScriptNPObject);
129 m_windowScriptNPObject = 0;
130 }
131 }
132
133 void ScriptController::clearForClose() 107 void ScriptController::clearForClose()
134 { 108 {
135 double start = currentTime(); 109 double start = currentTime();
136 m_windowProxyManager->clearForClose(); 110 m_windowProxyManager->clearForClose();
137 Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearFo rClose", (currentTime() - start) * 1000, 0, 10000, 50); 111 Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearFo rClose", (currentTime() - start) * 1000, 0, 10000, 50);
138 } 112 }
139 113
140 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin) 114 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin)
141 { 115 {
142 m_windowProxyManager->mainWorldProxy()->updateSecurityOrigin(origin); 116 m_windowProxyManager->mainWorldProxy()->updateSecurityOrigin(origin);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 202 }
229 203
230 TextPosition ScriptController::eventHandlerPosition() const 204 TextPosition ScriptController::eventHandlerPosition() const
231 { 205 {
232 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser(); 206 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser();
233 if (parser) 207 if (parser)
234 return parser->textPosition(); 208 return parser->textPosition();
235 return TextPosition::minimumPosition(); 209 return TextPosition::minimumPosition();
236 } 210 }
237 211
238 // Create a V8 object with an interceptor of NPObjectPropertyGetter.
239 bool ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object)
240 {
241 ScriptState* scriptState = ScriptState::forMainWorld(frame);
242 if (!scriptState->contextIsValid())
243 return false;
244
245 ScriptState::Scope scope(scriptState);
246 v8::Local<v8::Object> value = createV8ObjectForNPObject(isolate(), object, 0 );
247
248 // Attach to the global object.
249 return v8CallBoolean(scriptState->context()->Global()->Set(scriptState->cont ext(), v8String(isolate(), key), value));
250 }
251
252 void ScriptController::enableEval() 212 void ScriptController::enableEval()
253 { 213 {
254 if (!m_windowProxyManager->mainWorldProxy()->isContextInitialized()) 214 if (!m_windowProxyManager->mainWorldProxy()->isContextInitialized())
255 return; 215 return;
256 v8::HandleScope handleScope(isolate()); 216 v8::HandleScope handleScope(isolate());
257 m_windowProxyManager->mainWorldProxy()->context()->AllowCodeGenerationFromSt rings(true); 217 m_windowProxyManager->mainWorldProxy()->context()->AllowCodeGenerationFromSt rings(true);
258 } 218 }
259 219
260 void ScriptController::disableEval(const String& errorMessage) 220 void ScriptController::disableEval(const String& errorMessage)
261 { 221 {
(...skipping 11 matching lines...) Expand all
273 233
274 if (!widget->isPluginView()) 234 if (!widget->isPluginView())
275 return nullptr; 235 return nullptr;
276 236
277 v8::HandleScope handleScope(isolate()); 237 v8::HandleScope handleScope(isolate());
278 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate()); 238 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate());
279 239
280 if (scriptableObject.IsEmpty()) 240 if (scriptableObject.IsEmpty())
281 return nullptr; 241 return nullptr;
282 242
283 // LocalFrame Memory Management for NPObjects
284 // -------------------------------------
285 // NPObjects are treated differently than other objects wrapped by JS.
286 // NPObjects can be created either by the browser (e.g. the main
287 // window object) or by the plugin (the main plugin object
288 // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame
289 // is especially careful to ensure NPObjects terminate at frame teardown bec ause
290 // if a plugin leaks a reference, it could leak its objects (or the browser' s objects).
291 //
292 // The LocalFrame maintains a list of plugin objects (m_pluginObjects)
293 // which it can use to quickly find the wrapped embed object.
294 //
295 // Inside the NPRuntime, we've added a few methods for registering
296 // wrapped NPObjects. The purpose of the registration is because
297 // javascript garbage collection is non-deterministic, yet we need to
298 // be able to tear down the plugin objects immediately. When an object
299 // is registered, javascript can use it. When the object is destroyed,
300 // or when the object's "owning" object is destroyed, the object will
301 // be un-registered, and the javascript engine must not use it.
302 //
303 // Inside the javascript engine, the engine can keep a reference to the
304 // NPObject as part of its wrapper. However, before accessing the object
305 // it must consult the _NPN_Registry.
306
307 if (isWrappedNPObject(scriptableObject)) {
308 // Track the plugin object. We've been given a reference to the object.
309 m_pluginObjects.set(widget, v8ObjectToNPObject(scriptableObject));
310 }
311
312 return SharedPersistent<v8::Object>::create(scriptableObject, isolate()); 243 return SharedPersistent<v8::Object>::create(scriptableObject, isolate());
313 } 244 }
314 245
315 void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
316 {
317 PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
318 if (it == m_pluginObjects.end())
319 return;
320 _NPN_UnregisterObject(it->value);
321 _NPN_ReleaseObject(it->value);
322 m_pluginObjects.remove(it);
323 }
324
325 V8Extensions& ScriptController::registeredExtensions() 246 V8Extensions& ScriptController::registeredExtensions()
326 { 247 {
327 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ()); 248 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ());
328 return extensions; 249 return extensions;
329 } 250 }
330 251
331 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension) 252 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension)
332 { 253 {
333 const V8Extensions& extensions = registeredExtensions(); 254 const V8Extensions& extensions = registeredExtensions();
334 for (size_t i = 0; i < extensions.size(); ++i) { 255 for (size_t i = 0; i < extensions.size(); ++i) {
335 if (extensions[i] == extension) 256 if (extensions[i] == extension)
336 return; 257 return;
337 } 258 }
338 v8::RegisterExtension(extension); 259 v8::RegisterExtension(extension);
339 registeredExtensions().append(extension); 260 registeredExtensions().append(extension);
340 } 261 }
341 262
342 static NPObject* createNoScriptObject()
343 {
344 notImplemented();
345 return 0;
346 }
347
348 static NPObject* createScriptObject(LocalFrame* frame, v8::Isolate* isolate)
349 {
350 ScriptState* scriptState = ScriptState::forMainWorld(frame);
351 if (!scriptState->contextIsValid())
352 return createNoScriptObject();
353
354 ScriptState::Scope scope(scriptState);
355 LocalDOMWindow* window = frame->localDOMWindow();
356 v8::Local<v8::Value> global = toV8(window, scriptState->context()->Global(), scriptState->isolate());
357 if (global.IsEmpty())
358 return createNoScriptObject();
359 ASSERT(global->IsObject());
360 return npCreateV8ScriptObject(isolate, 0, v8::Local<v8::Object>::Cast(global ), window);
361 }
362
363 NPObject* ScriptController::windowScriptNPObject()
364 {
365 if (m_windowScriptNPObject)
366 return m_windowScriptNPObject;
367
368 if (canExecuteScripts(NotAboutToExecuteScript)) {
369 // JavaScript is enabled, so there is a JavaScript window object.
370 // Return an NPObject bound to the window object.
371 m_windowScriptNPObject = createScriptObject(frame(), isolate());
372 _NPN_RegisterObject(m_windowScriptNPObject, 0);
373 } else {
374 // JavaScript is not enabled, so we cannot bind the NPObject to the
375 // JavaScript window object. Instead, we create an NPObject of a
376 // different class, one which is not bound to a JavaScript object.
377 m_windowScriptNPObject = createNoScriptObject();
378 }
379 return m_windowScriptNPObject;
380 }
381
382 NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement * plugin)
383 {
384 // Can't create NPObjects when JavaScript is disabled.
385 if (!canExecuteScripts(NotAboutToExecuteScript))
386 return createNoScriptObject();
387
388 ScriptState* scriptState = ScriptState::forMainWorld(frame());
389 if (!scriptState->contextIsValid())
390 return createNoScriptObject();
391
392 ScriptState::Scope scope(scriptState);
393 LocalDOMWindow* window = frame()->localDOMWindow();
394 v8::Local<v8::Value> v8plugin = toV8(plugin, scriptState->context()->Global( ), scriptState->isolate());
395 if (v8plugin.IsEmpty() || !v8plugin->IsObject())
396 return createNoScriptObject();
397
398 return npCreateV8ScriptObject(scriptState->isolate(), 0, v8::Local<v8::Objec t>::Cast(v8plugin), window);
399 }
400
401 void ScriptController::clearWindowProxy() 263 void ScriptController::clearWindowProxy()
402 { 264 {
403 // V8 binding expects ScriptController::clearWindowProxy only be called 265 // V8 binding expects ScriptController::clearWindowProxy only be called
404 // when a frame is loading a new page. This creates a new context for the ne w page. 266 // when a frame is loading a new page. This creates a new context for the ne w page.
405 267
406 double start = currentTime(); 268 double start = currentTime();
407 // The V8 context must be available for |clearScriptObjects()|.
408 // The below call must be before |clearForNavigation()| which disposes the V 8 context.
409 clearScriptObjects();
410 269
411 m_windowProxyManager->clearForNavigation(); 270 m_windowProxyManager->clearForNavigation();
412 Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearWi ndowProxy", (currentTime() - start) * 1000, 0, 10000, 50); 271 Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearWi ndowProxy", (currentTime() - start) * 1000, 0, 10000, 50);
413 } 272 }
414 273
415 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value) 274 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value)
416 { 275 {
417 isolate->SetCaptureStackTraceForUncaughtExceptions(value, ScriptCallStack::m axCallStackSizeToCapture, stackTraceOptions); 276 isolate->SetCaptureStackTraceForUncaughtExceptions(value, ScriptCallStack::m axCallStackSizeToCapture, stackTraceOptions);
418 } 277 }
419 278
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 for (size_t i = 0; i < resultArray->Length(); ++i) { 455 for (size_t i = 0; i < resultArray->Length(); ++i) {
597 v8::Local<v8::Value> value; 456 v8::Local<v8::Value> value;
598 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value)) 457 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value))
599 return; 458 return;
600 results->append(value); 459 results->append(value);
601 } 460 }
602 } 461 }
603 } 462 }
604 463
605 } // namespace blink 464 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698