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 3// found in the LICENSE file. 4 5(function(global, utils, extrasUtils) { 6 7"use strict"; 8 9%CheckIsBootstrapping(); 10 11// ----------------------------------------------------------------------- 12// Utils 13 14var imports = UNDEFINED; 15var exports_container = %ExportFromRuntime({}); 16 17// Export to other scripts. 18function Export(f) { 19 f(exports_container); 20} 21 22 23// Import from other scripts. The actual importing happens in PostNatives so 24// that we can import from scripts executed later. However, that means that 25// the import is not available until the very end. If the import needs to be 26// available immediately, use ImportNow. 27function Import(f) { 28 f.next = imports; 29 imports = f; 30} 31 32 33// Import immediately from exports of previous scripts. We need this for 34// functions called during bootstrapping. Hooking up imports in PostNatives 35// would be too late. 36function ImportNow(name) { 37 return exports_container[name]; 38} 39 40 41function InstallConstants(object, constants) { 42 %CheckIsBootstrapping(); 43 %OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1); 44 var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY; 45 for (var i = 0; i < constants.length; i += 2) { 46 var name = constants[i]; 47 var k = constants[i + 1]; 48 %AddNamedProperty(object, name, k, attributes); 49 } 50 %ToFastProperties(object); 51} 52 53 54// Prevents changes to the prototype of a built-in function. 55// The "prototype" property of the function object is made non-configurable, 56// and the prototype object is made non-extensible. The latter prevents 57// changing the __proto__ property. 58function SetUpLockedPrototype( 59 constructor, fields, methods) { 60 %CheckIsBootstrapping(); 61 var prototype = constructor.prototype; 62 // Install functions first, because this function is used to initialize 63 // PropertyDescriptor itself. 64 var property_count = (methods.length >> 1) + (fields ? fields.length : 0); 65 if (property_count >= 4) { 66 %OptimizeObjectForAddingMultipleProperties(prototype, property_count); 67 } 68 if (fields) { 69 for (var i = 0; i < fields.length; i++) { 70 %AddNamedProperty(prototype, fields[i], 71 UNDEFINED, DONT_ENUM | DONT_DELETE); 72 } 73 } 74 for (var i = 0; i < methods.length; i += 2) { 75 var key = methods[i]; 76 var f = methods[i + 1]; 77 %AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY); 78 %SetNativeFlag(f); 79 } 80 %InternalSetPrototype(prototype, null); 81 %ToFastProperties(prototype); 82} 83 84 85// ----------------------------------------------------------------------- 86// To be called by bootstrapper 87 88function PostNatives(utils) { 89 %CheckIsBootstrapping(); 90 91 for ( ; !IS_UNDEFINED(imports); imports = imports.next) { 92 imports(exports_container); 93 } 94 95 exports_container = UNDEFINED; 96 utils.Export = UNDEFINED; 97 utils.Import = UNDEFINED; 98 utils.ImportNow = UNDEFINED; 99 utils.PostNatives = UNDEFINED; 100} 101 102// ----------------------------------------------------------------------- 103 104%OptimizeObjectForAddingMultipleProperties(utils, 14); 105 106utils.Import = Import; 107utils.ImportNow = ImportNow; 108utils.Export = Export; 109utils.InstallConstants = InstallConstants; 110utils.SetUpLockedPrototype = SetUpLockedPrototype; 111utils.PostNatives = PostNatives; 112 113%ToFastProperties(utils); 114 115// ----------------------------------------------------------------------- 116 117%OptimizeObjectForAddingMultipleProperties(extrasUtils, 11); 118 119extrasUtils.logStackTrace = function logStackTrace() { 120 %DebugTrace(); 121}; 122 123extrasUtils.log = function log() { 124 let message = ''; 125 for (const arg of arguments) { 126 message += arg; 127 } 128 129 %GlobalPrint(message); 130}; 131 132// Extras need the ability to store private state on their objects without 133// exposing it to the outside world. 134 135extrasUtils.createPrivateSymbol = function createPrivateSymbol(name) { 136 return %CreatePrivateSymbol(name); 137}; 138 139// These functions are key for safe meta-programming: 140// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming 141// 142// Technically they could all be derived from combinations of 143// Function.prototype.{bind,call,apply} but that introduces lots of layers of 144// indirection. 145 146extrasUtils.uncurryThis = function uncurryThis(func) { 147 return function(thisArg, ...args) { 148 return %reflect_apply(func, thisArg, args); 149 }; 150}; 151 152extrasUtils.markPromiseAsHandled = function markPromiseAsHandled(promise) { 153 %PromiseMarkAsHandled(promise); 154}; 155 156extrasUtils.promiseState = function promiseState(promise) { 157 return %PromiseStatus(promise); 158}; 159 160// [[PromiseState]] values (for extrasUtils.promiseState()) 161// These values should be kept in sync with PromiseStatus in globals.h 162extrasUtils.kPROMISE_PENDING = 0; 163extrasUtils.kPROMISE_FULFILLED = 1; 164extrasUtils.kPROMISE_REJECTED = 2; 165 166%ToFastProperties(extrasUtils); 167 168}) 169