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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/V8BindingDesign.md

Issue 1542623004: Add documentation about Isolate, Context, World, Frames etc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Design of V8 bindings
2
3 This document explains key concepts in the V8 binding architecture
4 except the lifetime management of DOM wrappers.
5 See [V8GCController.md](V8GCController.md) to learn the lifetime management.
6
7 [TOC]
8
9 ## Isolate
10
11 An isolate is a concept of a thread in V8.
12 Isolates and threads are in 1:1 relationship.
13 One isolate is associated with the main thread.
14 One isolate is associated with one worker thread.
15
16 ## Context
17
18 A context is a concept of a global variable scope in V8.
19 Roughly speaking, one window object corresponds to one context.
20 For example, `<iframe>` has a window object different from a window object
21 of its parent frame. So the context of the `<iframe>` is different from
22 the context of the parent frame. Since these contexts create their own
23 global variable scopes, global variables and prototype chains of the `<iframe>`
24 are isolated from the ones of the parent frame.
25
26 Here is an example:
27
28 ```html
29 // main.html
30 <html><body>
31 <iframe src="iframe.html"></iframe>
32 <script>
33 var foo = 1234;
34 String.prototype.substr =
35 function (position, length) { // Hijacks String.prototype.substr
36 console.log(length);
37 return "hijacked";
38 };
39 </script>
40 </body></html>
41
42 // iframe.html
43 <script>
44 console.log(foo); // undefined
45 var bar = "aaaa".substr(0, 2); // Nothing is logged.
46 console.log(bar); // "aa"
47 </script>
48 ```
49
50 In summary, each frame has a window object.
51 Each window object has a context.
52 Each context has its own global variable scope and prototype chains.
53
54 ## Entered context and current context
55
56 A relationship between isolates and contexts is interesting.
57 One isolate has to execute JavaScripts in multiple frames,
58 each of which has its own context. This means that the context associated
59 with the isolate changes over time. In other words, the relationship between
60 isolates and contexts is 1:N over the lifetime of the isolate.
61
62 Here we have a concept of an entered context and a current context.
63 To understand the difference, you need to understand two kinds of
64 runtime stacks.
65
66 The first stack is a stack of JavaScript functions.
67 This stack is managed by V8. When one function calls another function,
68 the callee function is pushed onto the stack. When that function returns,
69 the function is popped from the stack and the control returns to the caller
70 function that is now on the top of the stack. Each function has
71 an associated context. We call the context of the function
72 that is currently running (i.e., the context of the function that is on the top
73 of the stack) a current context.
74
75 Here is an example:
76
77 ```html
78 // main.html
79 <html><body>
80 <iframe src="iframe.html"></iframe>
81 <script>
82 var iframe = document.querySelector("iframe");
83 iframe.onload = function () {
84 iframe.contentWindow.func();
85 }
86 </script>
87 </body></html>
88
89 // iframe.html
90 <script>
91 function func() {
92 ...;
93 }
94 </script>
95 ```
96
97 In the above example, at the point when func() is running,
98 the current context is the context of the `<iframe>`.
99
100 There is a second stack that operates on a much coarser granularity.
101 This stack is managed by V8 binding (not by V8).
102 When V8 binding invokes JavaScript, V8 binding creates a new context
Yuki 2015/12/24 07:15:15 Exactly speaking, this seems a little bit wrong.
haraken 2015/12/28 02:54:59 Reworded: creates a new context => enters a con
103 and pushes the context onto the stack.
104 The JavaScript starts running on the context. When the JavaScript finishes
105 and the control returns back to V8 binding, V8 binding pops the context
106 from the stack. Given that the control between V8 binding and V8 can be nested
107 (i.e., V8 binding invokes JavaScript, which calls into V8 binding,
108 which invokes another JavaScript etc), these contexts form a stack.
109 The pushing and popping are done by calling v8::Context::Enter() and
110 v8::Context::Exit() (or v8::Context::Scope). We call the most recently entered
111 context an entered context.
112
113 In the above example, at the point when func() is running,
114 the entered context is the context of the main frame
115 (not the context of `<iframe>`).
116
117 The entered context is a concept to implement the
118 [entry settings object](https://html.spec.whatwg.org/#entry-settings-object)
Yuki 2015/12/24 07:15:15 Let's link to the multipage version. https://html.
haraken 2015/12/28 02:54:59 Done.
119 of the HTML spec. The current context is a concept to implement the
120 [incumbent settings object](https://html.spec.whatwg.org/#incumbent-settings-obj ect)
Yuki 2015/12/24 07:15:15 Ditto. https://html.spec.whatwg.org/multipage/weba
haraken 2015/12/28 02:54:59 Done.
121 of the HTML spec.
122
123 In summary, the entered context is a context from which the current JavaScript
124 execution was started. The current context is a context of
125 the JavaScript function that is currently running.
126
127 ## World
128
129 A world is a concept to sandbox DOM wrappers among content scripts of
130 Chrome extensions. There are three kinds of worlds: a main world,
131 an isolated world and a worker world.
132 A main world is a world where a normal JavaScript downloaded from the web
133 is executed.
134 An isolated world is a world where a content script of a Chrome extension.
135 An isolate of the main thread has 1 main world and N isolated worlds.
136 An isolate of a worker thread has 1 worker world and 0 isolated world.
137 [This diagram](https://drive.google.com/file/d/0B1obCOyvTnPKQmJEWkVtOEN2TmM/view ?usp=sharing)
138 will be helpful to understand the relationship.
139
140 All worlds in one isolate share underlying C++ DOM objects,
141 but each world has its own DOM wrappers. That way the worlds in one isolate
142 can operate on the same C++ DOM object without sharing any DOM wrapper
143 among the worlds.
144
145 Also each world has its own context.
146 This means that each world has its own global variable scope and
147 prototype chains.
148
149 As a result of the sandboxing, the worlds in one isolate cannot share
150 any DOM wrappers or contexts but can share underlying C++ DOM objects.
151 The fact that no DOM wrappers or contexts are shared means that no JavaScript
152 objects are shared among the worlds. That way we guarantee the security model
153 that Chrome extensions doesn't share any JavaScript objects while sharing
154 the underlying C++ DOM objects. This sandbox allows the Chrome extensions to run
155 untrusted JavaScripts on a shared DOM structure.
156
157 (Note: An isolated world is a concept of V8 binding,
158 whereas an isolate and a context are a concept of V8.
159 V8 does not know what isolated worlds are in an isolate.)
160
161 In summary, an isolate of the main thread consists of 1 main world
162 and N isolated worlds. An isolate world of a worker thread consists of
Yuki 2015/12/24 07:15:15 s/An isolate world of/An isolate of/
haraken 2015/12/28 02:54:59 Done.
163 1 worker world and 0 isolated world. All worlds in one isolate share the
164 underlying C++ DOM objects, but each world has its own DOM wrappers.
165 Each world has its own context and thus has its own global variable scope
166 and prototype chains.
167
168 ## A relationship between isolates, contexts, worlds and frames
169
170 Let's wrap up the relationship between isolates, contexts, worlds and frames.
171
172 * As a requirement of the DOM side, one HTML page has N frames.
173 Each frame has its own context.
174
175 * As a requirement of the JavaScript side, one isolate has M worlds.
176 Each world has its own context.
177
178 As a result, when we execute the main thread where N frames and M worlds
179 are involved, there exists N * M contexts. In other words, one context is
180 created for each pair of (frame, world).
181 [This diagram](https://drive.google.com/file/d/0B1obCOyvTnPKSERSMmpRVjVKQWc/view ?usp=sharing)
182 will be helpful to understand the relationship.
183
184 The main thread can have only one current context at one time,
185 but the main thread can have the N * M contexts over its lifetime.
186 For example, when the main thread is operating on a frame X using a JavaScript
187 in a world Y, the current context is set to a context for the pair of (X, Y).
188 The current context of the main thread changes over its lifetime.
189
190 On the other hand, a worker thread has 0 frame and 1 world.
191 Thus a worker thread has only 1 context.
192 The current context of the worker thread never changes.
193
194 ## DOM wrappers and worlds
195
196 For compatibility reasons (although this is not speced),
197 we need to make sure that the same DOM wrapper is returned to JavaScript
198 as long as the underlying C++ DOM object is alive.
199 We should not return different DOM wrappers for the same C++ DOM object.
200
201 Here is an example:
202
203 ```html
204 var div = document.createElement("div");
205 div.foo = 1234; // expando
206 var p = document.createElement("p");
207 p.appendChild(div);
208 div = null;
209 gc();
210 console.log(p.firstChild.foo); // This should be 1234, not undefined
211 ```
212
213 To accomplish the semantics that the same DOM wrapper is returned to JavaScript
214 as long as the underlying C++ DOM object is alive, we need a mapping
215 from the C++ DOM objects to the DOM wrappers.
216 In addition, we need to sandbox DOM wrappers in each world.
217 To meet the requirements, we make each world hold a DOM wrapper storage
218 that stores a mapping from the C++ DOM objects to the DOM wrappers in that world .
219
220 As a result, we have multiple DOM wrapper storages in one isolate.
221 The mapping of the main world is written in ScriptWrappable.
222 If ScriptWrappable::m_wrapper has a non-empty value, it is a DOM wrapper of
223 the C++ DOM object of the main world.
224 The mapping of other worlds are written in DOMWrapperMap.
225
226 ## DOM wrappers and contexts
227
228 When you create a new DOM wrapper, you need to choose a correct context
229 on which the DOM wrapper is created. If you create a new DOM wrapper in a
230 wrong context, you will end up with leaking JavaScript objects to other
231 contexts, which is very likely to cause security issues.
232
233 Here is an example:
234
235 ```html
236 // main.html
237 <html><body>
238 <iframe src="iframe.html"></iframe>
239 <script>
240 var iframe = document.querySelector("iframe");
241 iframe; // The wrapper of the iframe should be created in the context of the ma in frame.
242 iframe.contentDocument; // The wrapper of the document should be created in the context of the iframe.
243 iframe.contentDocument.addEventListener("click",
244 function (event) { // The wrapper of the event should be created in the con text of the iframe.
245 event.target;
246 });
247 </script>
248 </body></html>
249
250 // iframe.html
251 <script>
252 </script>
253 ```
254
255 To make sure that a DOM wrapper is created in a correct context, you need to
256 make sure that the current context must be set to the correct context
257 whenever you call toV8(). If you're not sure what context to use,
258 ask haraken@chromium.org.
259
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698