• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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