OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project 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 (function(global, utils) { | 5 (function(global, utils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
11 // ----------------------------------------------------------------------- | 11 // ----------------------------------------------------------------------- |
12 // Utils | 12 // Utils |
13 | 13 |
14 var imports = UNDEFINED; | 14 var imports = UNDEFINED; |
15 var exports = UNDEFINED; | 15 var exports = UNDEFINED; |
16 var imports_from_experimental = UNDEFINED; | |
17 | 16 |
18 | 17 |
19 // Export to other scripts. | 18 utils.Export = function Export(f) { |
20 // In normal natives, this exports functions to other normal natives. | |
21 // In experimental natives, this exports to other experimental natives and | |
22 // to normal natives that import using utils.ImportFromExperimental. | |
23 function Export(f) { | |
24 f.next = exports; | 19 f.next = exports; |
25 exports = f; | 20 exports = f; |
26 }; | 21 }; |
27 | 22 |
28 | 23 |
29 // Import from other scripts. | 24 utils.Import = function Import(f) { |
30 // In normal natives, this imports from other normal natives. | |
31 // In experimental natives, this imports from other experimental natives and | |
32 // whitelisted exports from normal natives. | |
33 function Import(f) { | |
34 f.next = imports; | 25 f.next = imports; |
35 imports = f; | 26 imports = f; |
36 }; | 27 }; |
37 | 28 |
38 | |
39 // In normal natives, import from experimental natives. | |
40 // Not callable from experimental natives. | |
41 function ImportFromExperimental(f) { | |
42 f.next = imports_from_experimental; | |
43 imports_from_experimental = f; | |
44 }; | |
45 | |
46 | |
47 function SetFunctionName(f, name, prefix) { | |
48 if (IS_SYMBOL(name)) { | |
49 name = "[" + %SymbolDescription(name) + "]"; | |
50 } | |
51 if (IS_UNDEFINED(prefix)) { | |
52 %FunctionSetName(f, name); | |
53 } else { | |
54 %FunctionSetName(f, prefix + " " + name); | |
55 } | |
56 } | |
57 | |
58 | |
59 function InstallConstants(object, constants) { | |
60 %CheckIsBootstrapping(); | |
61 %OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1); | |
62 var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY; | |
63 for (var i = 0; i < constants.length; i += 2) { | |
64 var name = constants[i]; | |
65 var k = constants[i + 1]; | |
66 %AddNamedProperty(object, name, k, attributes); | |
67 } | |
68 %ToFastProperties(object); | |
69 } | |
70 | |
71 | |
72 function InstallFunctions(object, attributes, functions) { | |
73 %CheckIsBootstrapping(); | |
74 %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1); | |
75 for (var i = 0; i < functions.length; i += 2) { | |
76 var key = functions[i]; | |
77 var f = functions[i + 1]; | |
78 SetFunctionName(f, key); | |
79 %FunctionRemovePrototype(f); | |
80 %AddNamedProperty(object, key, f, attributes); | |
81 %SetNativeFlag(f); | |
82 } | |
83 %ToFastProperties(object); | |
84 } | |
85 | |
86 | |
87 // Helper function to install a getter-only accessor property. | |
88 function InstallGetter(object, name, getter, attributes) { | |
89 %CheckIsBootstrapping(); | |
90 if (typeof attributes == "undefined") { | |
91 attributes = DONT_ENUM; | |
92 } | |
93 SetFunctionName(getter, name, "get"); | |
94 %FunctionRemovePrototype(getter); | |
95 %DefineAccessorPropertyUnchecked(object, name, getter, null, attributes); | |
96 %SetNativeFlag(getter); | |
97 } | |
98 | |
99 | |
100 // Helper function to install a getter/setter accessor property. | |
101 function InstallGetterSetter(object, name, getter, setter) { | |
102 %CheckIsBootstrapping(); | |
103 SetFunctionName(getter, name, "get"); | |
104 SetFunctionName(setter, name, "set"); | |
105 %FunctionRemovePrototype(getter); | |
106 %FunctionRemovePrototype(setter); | |
107 %DefineAccessorPropertyUnchecked(object, name, getter, setter, DONT_ENUM); | |
108 %SetNativeFlag(getter); | |
109 %SetNativeFlag(setter); | |
110 } | |
111 | |
112 | |
113 // Prevents changes to the prototype of a built-in function. | |
114 // The "prototype" property of the function object is made non-configurable, | |
115 // and the prototype object is made non-extensible. The latter prevents | |
116 // changing the __proto__ property. | |
117 function SetUpLockedPrototype( | |
118 constructor, fields, methods) { | |
119 %CheckIsBootstrapping(); | |
120 var prototype = constructor.prototype; | |
121 // Install functions first, because this function is used to initialize | |
122 // PropertyDescriptor itself. | |
123 var property_count = (methods.length >> 1) + (fields ? fields.length : 0); | |
124 if (property_count >= 4) { | |
125 %OptimizeObjectForAddingMultipleProperties(prototype, property_count); | |
126 } | |
127 if (fields) { | |
128 for (var i = 0; i < fields.length; i++) { | |
129 %AddNamedProperty(prototype, fields[i], | |
130 UNDEFINED, DONT_ENUM | DONT_DELETE); | |
131 } | |
132 } | |
133 for (var i = 0; i < methods.length; i += 2) { | |
134 var key = methods[i]; | |
135 var f = methods[i + 1]; | |
136 %AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY); | |
137 %SetNativeFlag(f); | |
138 } | |
139 %InternalSetPrototype(prototype, null); | |
140 %ToFastProperties(prototype); | |
141 } | |
142 | |
143 // ----------------------------------------------------------------------- | 29 // ----------------------------------------------------------------------- |
144 // To be called by bootstrapper | 30 // To be called by bootstrapper |
145 | 31 |
146 var experimental_exports = UNDEFINED; | 32 utils.PostNatives = function() { |
147 | |
148 function PostNatives(utils) { | |
149 %CheckIsBootstrapping(); | 33 %CheckIsBootstrapping(); |
150 | 34 |
151 var container = {}; | 35 var container = {}; |
152 for ( ; !IS_UNDEFINED(exports); exports = exports.next) exports(container); | 36 for ( ; !IS_UNDEFINED(exports); exports = exports.next) exports(container); |
153 for ( ; !IS_UNDEFINED(imports); imports = imports.next) imports(container); | 37 for ( ; !IS_UNDEFINED(imports); imports = imports.next) imports(container); |
154 | 38 |
155 // Whitelist of exports from normal natives to experimental natives. | |
156 var expose_to_experimental = [ | 39 var expose_to_experimental = [ |
157 "GetIterator", | |
158 "GetMethod", | |
159 "InnerArrayEvery", | |
160 "InnerArrayFilter", | |
161 "InnerArrayForEach", | |
162 "InnerArrayIndexOf", | |
163 "InnerArrayLastIndexOf", | |
164 "InnerArrayMap", | |
165 "InnerArrayReverse", | |
166 "InnerArraySome", | |
167 "InnerArraySort", | |
168 "IsNaN", | |
169 "MathMax", | 40 "MathMax", |
170 "MathMin", | 41 "MathMin", |
171 "ObjectIsFrozen", | |
172 "OwnPropertyKeys", | |
173 "ToNameArray", | |
174 ]; | 42 ]; |
175 experimental_exports = {}; | 43 var experimental = {}; |
176 %OptimizeObjectForAddingMultipleProperties( | 44 %OptimizeObjectForAddingMultipleProperties( |
177 experimental_exports, expose_to_experimental.length); | 45 experimental, expose_to_experimental.length); |
178 for (var key of expose_to_experimental) { | 46 for (var key of expose_to_experimental) experimental[key] = container[key]; |
179 experimental_exports[key] = container[key]; | 47 %ToFastProperties(experimental); |
180 } | |
181 %ToFastProperties(experimental_exports); | |
182 container = UNDEFINED; | 48 container = UNDEFINED; |
183 | 49 |
| 50 utils.Export = UNDEFINED; |
184 utils.PostNatives = UNDEFINED; | 51 utils.PostNatives = UNDEFINED; |
185 utils.ImportFromExperimental = UNDEFINED; | 52 utils.Import = function ImportFromExperimental(f) { |
| 53 f(experimental); |
| 54 }; |
186 }; | 55 }; |
187 | 56 |
188 | |
189 function PostExperimentals(utils) { | |
190 %CheckIsBootstrapping(); | |
191 | |
192 for ( ; !IS_UNDEFINED(exports); exports = exports.next) { | |
193 exports(experimental_exports); | |
194 } | |
195 for ( ; !IS_UNDEFINED(imports); imports = imports.next) { | |
196 imports(experimental_exports); | |
197 } | |
198 for ( ; !IS_UNDEFINED(imports_from_experimental); | |
199 imports_from_experimental = imports_from_experimental.next) { | |
200 imports_from_experimental(experimental_exports); | |
201 } | |
202 | |
203 experimental_exports = UNDEFINED; | |
204 | |
205 utils.PostExperimentals = UNDEFINED; | |
206 utils.Import = UNDEFINED; | |
207 utils.Export = UNDEFINED; | |
208 }; | |
209 | |
210 // ----------------------------------------------------------------------- | |
211 | |
212 InstallFunctions(utils, NONE, [ | |
213 "Import", Import, | |
214 "Export", Export, | |
215 "ImportFromExperimental", ImportFromExperimental, | |
216 "SetFunctionName", SetFunctionName, | |
217 "InstallConstants", InstallConstants, | |
218 "InstallFunctions", InstallFunctions, | |
219 "InstallGetter", InstallGetter, | |
220 "InstallGetterSetter", InstallGetterSetter, | |
221 "SetUpLockedPrototype", SetUpLockedPrototype, | |
222 "PostNatives", PostNatives, | |
223 "PostExperimentals", PostExperimentals, | |
224 ]); | |
225 | |
226 }) | 57 }) |
OLD | NEW |