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