// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

(function(global, utils, extrasUtils) {

"use strict";

%CheckIsBootstrapping();

// -----------------------------------------------------------------------
// Utils

var imports = UNDEFINED;
var imports_from_experimental = UNDEFINED;
var exports_container = %ExportFromRuntime({});
var typed_array_setup = UNDEFINED;

// Register context value to be initialized with a typed array in
// Genesis::InitializeBuiltinTypedArrays.
function SetupTypedArray(f) {
  f.next = typed_array_setup;
  typed_array_setup = f;
}

// Export to other scripts.
// In normal natives, this exports functions to other normal natives.
// In experimental natives, this exports to other experimental natives and
// to normal natives that import using utils.ImportFromExperimental.
function Export(f) {
  f(exports_container);
}


// Import from other scripts. The actual importing happens in PostNatives and
// PostExperimental so that we can import from scripts executed later. However,
// that means that the import is not available until the very end. If the
// import needs to be available immediate, use ImportNow.
// In normal natives, this imports from other normal natives.
// In experimental natives, this imports from other experimental natives and
// whitelisted exports from normal natives.
function Import(f) {
  f.next = imports;
  imports = f;
}


// Import immediately from exports of previous scripts. We need this for
// functions called during bootstrapping. Hooking up imports in PostNatives
// would be too late.
function ImportNow(name) {
  return exports_container[name];
}


// In normal natives, import from experimental natives.
// Not callable from experimental natives.
function ImportFromExperimental(f) {
  f.next = imports_from_experimental;
  imports_from_experimental = f;
}


function SetFunctionName(f, name, prefix) {
  if (IS_SYMBOL(name)) {
    name = "[" + %SymbolDescription(name) + "]";
  }
  if (IS_UNDEFINED(prefix)) {
    %FunctionSetName(f, name);
  } else {
    %FunctionSetName(f, prefix + " " + name);
  }
}


function InstallConstants(object, constants) {
  %CheckIsBootstrapping();
  %OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1);
  var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
  for (var i = 0; i < constants.length; i += 2) {
    var name = constants[i];
    var k = constants[i + 1];
    %AddNamedProperty(object, name, k, attributes);
  }
  %ToFastProperties(object);
}


function InstallFunctions(object, attributes, functions) {
  %CheckIsBootstrapping();
  %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
  for (var i = 0; i < functions.length; i += 2) {
    var key = functions[i];
    var f = functions[i + 1];
    SetFunctionName(f, key);
    %FunctionRemovePrototype(f);
    %AddNamedProperty(object, key, f, attributes);
    %SetNativeFlag(f);
  }
  %ToFastProperties(object);
}


// Helper function to install a getter-only accessor property.
function InstallGetter(object, name, getter, attributes, prefix) {
  %CheckIsBootstrapping();
  if (IS_UNDEFINED(attributes)) attributes = DONT_ENUM;
  SetFunctionName(getter, name, IS_UNDEFINED(prefix) ? "get" : prefix);
  %FunctionRemovePrototype(getter);
  %DefineGetterPropertyUnchecked(object, name, getter, attributes);
  %SetNativeFlag(getter);
}


// Helper function to install a getter/setter accessor property.
function InstallGetterSetter(object, name, getter, setter, attributes) {
  %CheckIsBootstrapping();
  if (IS_UNDEFINED(attributes)) attributes = DONT_ENUM;
  SetFunctionName(getter, name, "get");
  SetFunctionName(setter, name, "set");
  %FunctionRemovePrototype(getter);
  %FunctionRemovePrototype(setter);
  %DefineAccessorPropertyUnchecked(object, name, getter, setter, DONT_ENUM);
  %SetNativeFlag(getter);
  %SetNativeFlag(setter);
}


function OverrideFunction(object, name, f, afterInitialBootstrap) {
  %CheckIsBootstrapping();
  %object_define_property(object, name, { value: f,
                                          writeable: true,
                                          configurable: true,
                                          enumerable: false });
  SetFunctionName(f, name);
  if (!afterInitialBootstrap) %FunctionRemovePrototype(f);
  %SetNativeFlag(f);
}


// Prevents changes to the prototype of a built-in function.
// The "prototype" property of the function object is made non-configurable,
// and the prototype object is made non-extensible. The latter prevents
// changing the __proto__ property.
function SetUpLockedPrototype(
    constructor, fields, methods) {
  %CheckIsBootstrapping();
  var prototype = constructor.prototype;
  // Install functions first, because this function is used to initialize
  // PropertyDescriptor itself.
  var property_count = (methods.length >> 1) + (fields ? fields.length : 0);
  if (property_count >= 4) {
    %OptimizeObjectForAddingMultipleProperties(prototype, property_count);
  }
  if (fields) {
    for (var i = 0; i < fields.length; i++) {
      %AddNamedProperty(prototype, fields[i],
                        UNDEFINED, DONT_ENUM | DONT_DELETE);
    }
  }
  for (var i = 0; i < methods.length; i += 2) {
    var key = methods[i];
    var f = methods[i + 1];
    %AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
    %SetNativeFlag(f);
  }
  %InternalSetPrototype(prototype, null);
  %ToFastProperties(prototype);
}


// -----------------------------------------------------------------------
// To be called by bootstrapper

function PostNatives(utils) {
  %CheckIsBootstrapping();

  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
    imports(exports_container);
  }

  // Whitelist of exports from normal natives to experimental natives and debug.
  var expose_list = [
    "AddBoundMethod",
    "ArrayToString",
    "AsyncFunctionNext",
    "AsyncFunctionThrow",
    "ErrorToString",
    "GetIterator",
    "GetMethod",
    "IntlParseDate",
    "IntlParseNumber",
    "IsNaN",
    "MakeError",
    "MakeRangeError",
    "MakeTypeError",
    "MapEntries",
    "MapIterator",
    "MapIteratorNext",
    "MaxSimple",
    "MinSimple",
    "NumberIsInteger",
    "PromiseChain",
    "PromiseDefer",
    "PromiseAccept",
    "PromiseCreateRejected",
    "PromiseCreateResolved",
    "PromiseThen",
    "RegExpSubclassExecJS",
    "RegExpSubclassMatch",
    "RegExpSubclassReplace",
    "RegExpSubclassSearch",
    "RegExpSubclassSplit",
    "RegExpSubclassTest",
    "SetIterator",
    "SetIteratorNext",
    "SetValues",
    "SymbolToString",
    "ToLocaleLowerCaseI18N",
    "ToLocaleUpperCaseI18N",
    "ToLowerCaseI18N",
    "ToPositiveInteger",
    "ToUpperCaseI18N",
    // From runtime:
    "is_concat_spreadable_symbol",
    "iterator_symbol",
    "promise_result_symbol",
    "promise_state_symbol",
    "object_freeze",
    "object_is_frozen",
    "object_is_sealed",
    "reflect_apply",
    "reflect_construct",
    "regexp_flags_symbol",
    "to_string_tag_symbol",
    "object_to_string",
    "species_symbol",
    "match_symbol",
    "replace_symbol",
    "search_symbol",
    "split_symbol",
  ];

  var filtered_exports = {};
  %OptimizeObjectForAddingMultipleProperties(
      filtered_exports, expose_list.length);
  for (var key of expose_list) {
    filtered_exports[key] = exports_container[key];
  }
  %ToFastProperties(filtered_exports);
  exports_container = filtered_exports;

  utils.PostNatives = UNDEFINED;
  utils.ImportFromExperimental = UNDEFINED;
}


function PostExperimentals(utils) {
  %CheckIsBootstrapping();
  %ExportExperimentalFromRuntime(exports_container);
  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
    imports(exports_container);
  }
  for ( ; !IS_UNDEFINED(imports_from_experimental);
          imports_from_experimental = imports_from_experimental.next) {
    imports_from_experimental(exports_container);
  }

  utils.Export = UNDEFINED;
  utils.PostDebug = UNDEFINED;
  utils.PostExperimentals = UNDEFINED;
  typed_array_setup = UNDEFINED;
}


function PostDebug(utils) {
  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
    imports(exports_container);
  }

  exports_container = UNDEFINED;

  utils.Export = UNDEFINED;
  utils.Import = UNDEFINED;
  utils.ImportNow = UNDEFINED;
  utils.PostDebug = UNDEFINED;
  utils.PostExperimentals = UNDEFINED;
  typed_array_setup = UNDEFINED;
}


function InitializeBuiltinTypedArrays(utils, rng_state, rempio2result) {
  var setup_list =  typed_array_setup;

  for ( ; !IS_UNDEFINED(setup_list); setup_list = setup_list.next) {
    setup_list(rng_state, rempio2result);
  }
}


// -----------------------------------------------------------------------

%OptimizeObjectForAddingMultipleProperties(utils, 14);

utils.Import = Import;
utils.ImportNow = ImportNow;
utils.Export = Export;
utils.ImportFromExperimental = ImportFromExperimental;
utils.SetFunctionName = SetFunctionName;
utils.InstallConstants = InstallConstants;
utils.InstallFunctions = InstallFunctions;
utils.InstallGetter = InstallGetter;
utils.InstallGetterSetter = InstallGetterSetter;
utils.OverrideFunction = OverrideFunction;
utils.SetUpLockedPrototype = SetUpLockedPrototype;
utils.PostNatives = PostNatives;
utils.PostExperimentals = PostExperimentals;
utils.PostDebug = PostDebug;

%ToFastProperties(utils);

// -----------------------------------------------------------------------

%OptimizeObjectForAddingMultipleProperties(extrasUtils, 5);

extrasUtils.logStackTrace = function logStackTrace() {
  %DebugTrace();
};

extrasUtils.log = function log() {
  let message = '';
  for (const arg of arguments) {
    message += arg;
  }

  %GlobalPrint(message);
};

// Extras need the ability to store private state on their objects without
// exposing it to the outside world.

extrasUtils.createPrivateSymbol = function createPrivateSymbol(name) {
  return %CreatePrivateSymbol(name);
};

// These functions are key for safe meta-programming:
// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
//
// Technically they could all be derived from combinations of
// Function.prototype.{bind,call,apply} but that introduces lots of layers of
// indirection and slowness given how un-optimized bind is.

extrasUtils.simpleBind = function simpleBind(func, thisArg) {
  return function(...args) {
    return %reflect_apply(func, thisArg, args);
  };
};

extrasUtils.uncurryThis = function uncurryThis(func) {
  return function(thisArg, ...args) {
    return %reflect_apply(func, thisArg, args);
  };
};

%ToFastProperties(extrasUtils);

})
