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 | 16 var imports_from_experimental = UNDEFINED; |
17 | 17 |
18 utils.Export = function Export(f) { | 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. |
| 23 function Export(f) { |
19 f.next = exports; | 24 f.next = exports; |
20 exports = f; | 25 exports = f; |
21 }; | 26 }; |
22 | 27 |
23 | 28 |
24 utils.Import = function Import(f) { | 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. |
| 33 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 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 |
29 // ----------------------------------------------------------------------- | 143 // ----------------------------------------------------------------------- |
30 // To be called by bootstrapper | 144 // To be called by bootstrapper |
31 | 145 |
32 utils.PostNatives = function() { | 146 var experimental_exports = UNDEFINED; |
| 147 |
| 148 function PostNatives(utils) { |
33 %CheckIsBootstrapping(); | 149 %CheckIsBootstrapping(); |
34 | 150 |
35 var container = {}; | 151 var container = {}; |
36 for ( ; !IS_UNDEFINED(exports); exports = exports.next) exports(container); | 152 for ( ; !IS_UNDEFINED(exports); exports = exports.next) exports(container); |
37 for ( ; !IS_UNDEFINED(imports); imports = imports.next) imports(container); | 153 for ( ; !IS_UNDEFINED(imports); imports = imports.next) imports(container); |
38 | 154 |
| 155 // Whitelist of exports from normal natives to experimental natives. |
39 var expose_to_experimental = [ | 156 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", |
40 "MathMax", | 169 "MathMax", |
41 "MathMin", | 170 "MathMin", |
| 171 "ObjectIsFrozen", |
| 172 "OwnPropertyKeys", |
| 173 "ToNameArray", |
42 ]; | 174 ]; |
43 var experimental = {}; | 175 experimental_exports = {}; |
44 %OptimizeObjectForAddingMultipleProperties( | 176 %OptimizeObjectForAddingMultipleProperties( |
45 experimental, expose_to_experimental.length); | 177 experimental_exports, expose_to_experimental.length); |
46 for (var key of expose_to_experimental) experimental[key] = container[key]; | 178 for (var key of expose_to_experimental) { |
47 %ToFastProperties(experimental); | 179 experimental_exports[key] = container[key]; |
| 180 } |
| 181 %ToFastProperties(experimental_exports); |
48 container = UNDEFINED; | 182 container = UNDEFINED; |
49 | 183 |
| 184 utils.PostNatives = UNDEFINED; |
| 185 utils.ImportFromExperimental = UNDEFINED; |
| 186 }; |
| 187 |
| 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; |
50 utils.Export = UNDEFINED; | 207 utils.Export = UNDEFINED; |
51 utils.PostNatives = UNDEFINED; | 208 }; |
52 utils.Import = function ImportFromExperimental(f) { | 209 |
53 f(experimental); | 210 // ----------------------------------------------------------------------- |
54 }; | 211 |
55 }; | 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 ]); |
56 | 225 |
57 }) | 226 }) |
OLD | NEW |