The last one is about a very important function initcontextifneeded, here specifically to analyze This function:
Create a new environment and setup the global object.
//
The global object corresponds to a Domwindow instance. However, to
Allow properties of the JS Domwindow instance to be shadowed, we
Use a shadow object as the global object and use the JS Domwindow
Instance as the prototype for that Shadow object. The JS Domwindow
Instance is undetectable from JavaScript code because the __proto__
Accessors skip that object.
//
The Shadow object and the Domwindow instance are seen as one object
from JavaScript. The JavaScript object that corresponds to a
Domwindow instance is the Shadow object. When mapping a Domwindow
Instance to a V8 object, we return the Shadow object.
//
To implement Split-window, see
1) https://bugs.webkit.org/show_bug.cgi?id=17249
2) Https://wiki.mozilla.org/Gecko:SplitWindow
3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
We need to split the shadow object further into the objects:
An outer window and an inner window. The inner window is the hidden
Prototype of the outer window. The inner window is the default
Global object of the context. A variable declared in the global
Scope is a property of the inner window.
//
The outer window sticks to a Frame, it's exposed to JavaScript
Via Window.window, window.self, window.parent, etc. The outer window
Have a security token which is the domain. The outer window cannot
Has its own properties. Window.foo = ' x ' is delegated to the
Inner window.
//
When a frame navigates to a new page, the inner window is cut off
The outer window, and the Outer window identify is preserved for
The frame. However, a new inner window is created for the new page.
If There is JS code holds a closure to the old inner window,
It won ' t is able to reach the outer window via its global object.
BOOL V8domwindowshell::initcontextifneeded ()
{
Bail out if the context has already been initialized.
if (!m_context. IsEmpty ())
return false;
Create a handle scope for all local handles.
V8::handlescope Handlescope;
Setup the security handlers and message listener. This is only have
To is done once.
static bool isv8initialized = FALSE;
if (!isv8initialized) {
Tells V8 not to call the default OOM handler, binding code
would handle it.
V8::v8::ignoreoutofmemoryexception ();
V8::v8::setfatalerrorhandler (REPORTFATALERRORINV8);
V8::v8::setglobalgcprologuecallback (&v8gccontroller::gcprologue);
V8::v8::setglobalgcepiloguecallback (&v8gccontroller::gcepilogue);
V8::v8::addmessagelistener (&v8uncaughtexceptionhandler);
V8::v8::setfailedaccesscheckcallbackfunction (reportunsafejavascriptaccess);
#if ENABLE (Javascript_debugger)
Scriptprofiler::initialize ();
#endif
Isv8initialized = true;
}
M_context = Createnewcontext (m_global, 0);
if (M_context. IsEmpty ())
return false;
v8::local<v8::context> V8context = v8::local<v8::context>::new (M_context);
V8::context::scope Contextscope (V8context);
Store the first global object created so we can reuse it.
if (M_global. IsEmpty ()) {
M_global = V8::P ersistent<v8::object>::new (V8context->global ());
Bail out if allocation of the first global objects fails.
if (M_global. IsEmpty ()) {
Disposecontexthandles ();
return false;
}
#ifndef Ndebug
V8gccontroller::registerglobalhandle (PROXY, this, m_global);
#endif
}
if (!installhiddenobjectprototype (V8context)) {
Disposecontexthandles ();
return false;
}
if (!installdomwindow (V8context, M_frame->domwindow ())) {
Disposecontexthandles ();
return false;
}
UpdateDocument ();
Setsecuritytoken ();
M_frame->loader ()->client ()->didcreatescriptcontextforframe ();
Fixme:this is wrong. We should actually do the proper world once
We do isolated worlds the WebCore.
M_frame->loader ()->dispatchdidclearwindowobjectinworld (0);
return true;
}
There are a lot of English comments in the front, but also explain the function of the functions, first to translate the comments, but also convenient for later viewing:
Create a new environment and establish a global object
//
The JavaScript global object corresponds to a Domwindow instance.
However, in order for the properties of the Domwindow instance to be hidden, we use a shadow object as a global object and as a property of the shadow object using the JS Domwindow instance.
The JS Domwindow instance is not detected in the JS code because the __proto__ accessor skips over the object.
Shadow objects and Domwindow instances are considered the same object in JavaScript. The JavaScript object that corresponds to a Domwindow instance is actually a shadow object.
When mapping an Domwindow instance to a V8 object, we return the Shadow object.
//
//
To implement the Detach window, refer to:
1) https://bugs.webkit.org/show_bug.cgi?id=17249
2) Https://wiki.mozilla.org/Gecko:SplitWindow
3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
We need to divide the hidden object into two objects:
An external window and an internal window. The internal window is the hidden prototype (prototype) of the external window. The internal window is the default global object for the context. A variable declaration at the global scope is an attribute of the inner window.
//
The external window is related to a frame, which is exposed to JavaScript through calls such as window.window,window.self,window.parent. The external window has a secure range field. So window.foo = ' X ' This represents only the internal window.
//
When a frame navigates to a new page, the internal window is cut off from the external window, and the external window flag is used to save the frame. A new internal window, however, is used to create a new page. If a JS code has a closure of a previous internal window, it cannot be accessed through the global object to the external window.
Inside this function is a bit similar to the one previously said, creating Handlescope objects for all local handle, creating contexts, associating contexts to scopes.
After these steps there is a updatedocument (); Initializes the JS context for the new document. Initcontextifneeded is called in UpdateDocument (), why updatedocument This function calls initcontextifneeded? See note:
There is a existing JavaScript wrapper for the global object
of this frame. JavaScript code in other frames might hold a
Reference to this wrapper. We eagerly initialize the JavaScript
Context for the new document, Access on the
Global object Wrapper succeed.
There is a global object JS shell for this frame. The JS code in the other frame may have a reference to this shell. We are eager to initialize the JS context for this new document in order to be able to successfully access the shell of the global object.
In this updatedocument, in addition to the initialization context, update the Wrapercache of the document, as well as update the JS security start and security fields.
If you have any questions, you are welcome to point out
V8 engine initcontextifneeded (...) Function