/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.objects;

import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.JSType.isString;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.SwitchPoint;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.api.scripting.ClassFilter;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Getter;
import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.Setter;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ECMAErrors;
import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.GlobalConstants;
import jdk.nashorn.internal.runtime.GlobalFunctions;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.NativeJavaPackage;
import jdk.nashorn.internal.runtime.PropertyDescriptor;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.Scope;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.runtime.Specialization;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.regexp.RegExpResult;
import jdk.nashorn.internal.scripts.JD;
import jdk.nashorn.internal.scripts.JO;
import jdk.nashorn.tools.ShellFunctions;

/**
 * Representation of global scope.
 */
@ScriptClass("Global")
public final class Global extends Scope {
    // This special value is used to flag a lazily initialized global property.
    // This also serves as placeholder value used in place of a location property
    // (__FILE__, __DIR__, __LINE__)
    private static final Object LAZY_SENTINEL = new Object();

    private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
    private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);

    /**
     * Optimistic builtin names that require switchpoint invalidation
     * upon assignment. Overly conservative, but works for now, to avoid
     * any complicated scope checks and especially heavy weight guards
     * like
     *
     * <pre>
     *     public boolean setterGuard(final Object receiver) {
     *         final Global          global = Global.instance();
     *         final ScriptObject    sobj   = global.getFunctionPrototype();
     *         final Object          apply  = sobj.get("apply");
     *         return apply == receiver;
     *     }
     * </pre>
     *
     * Naturally, checking for builtin classes like NativeFunction is cheaper,
     * it's when you start adding property checks for said builtins you have
     * problems with guard speed.
     */

    /** Nashorn extension: arguments array */
    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
    public Object arguments;

    /** ECMA 15.1.2.2 parseInt (string , radix) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object parseInt;

    /** ECMA 15.1.2.3 parseFloat (string) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object parseFloat;

    /** ECMA 15.1.2.4 isNaN (number) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object isNaN;

    /** ECMA 15.1.2.5 isFinite (number) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object isFinite;

    /** ECMA 15.1.3.3 encodeURI */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object encodeURI;

    /** ECMA 15.1.3.4 encodeURIComponent */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object encodeURIComponent;

    /** ECMA 15.1.3.1 decodeURI */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object decodeURI;

    /** ECMA 15.1.3.2 decodeURIComponent */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object decodeURIComponent;

    /** ECMA B.2.1 escape (string) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object escape;

    /** ECMA B.2.2 unescape (string) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object unescape;

    /** Nashorn extension: global.print */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object print;

    /** Nashorn extension: global.load */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object load;

    /** Nashorn extension: global.loadWithNewGlobal */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object loadWithNewGlobal;

    /** Nashorn extension: global.exit */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object exit;

    /** Nashorn extension: global.quit */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object quit;

    /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final double NaN = Double.NaN;

    /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final double Infinity = Double.POSITIVE_INFINITY;

    /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final Object undefined = UNDEFINED;

    /** ECMA 15.1.2.1 eval(x) */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object eval;

    /** ECMA 15.1.4.1 Object constructor. */
    @Property(name = "Object", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object object;

    /** ECMA 15.1.4.2 Function constructor. */
    @Property(name = "Function", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object function;

    /** ECMA 15.1.4.3 Array constructor. */
    @Property(name = "Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object array;

    /** ECMA 15.1.4.4 String constructor */
    @Property(name = "String", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object string;

    /** ECMA 15.1.4.5 Boolean constructor */
    @Property(name = "Boolean", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object _boolean;

    /** ECMA 15.1.4.6 - Number constructor */
    @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object number;

    /**
     * Getter for ECMA 15.1.4.7 Date property
     *
     * @param self self reference
     * @return Date property value
     */
    @Getter(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getDate(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.date == LAZY_SENTINEL) {
            global.date = global.getBuiltinDate();
        }
        return global.date;
    }

    /**
     * Setter for ECMA 15.1.4.7 Date property
     *
     * @param self self reference
     * @param value value for the Date property
     */
    @Setter(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
    public static void setDate(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.date = value;
    }

    private volatile Object date = LAZY_SENTINEL;

    /**
     * Getter for ECMA 15.1.4.8 RegExp property
     *
     * @param self self reference
     * @return RegExp property value
     */
    @Getter(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getRegExp(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.regexp == LAZY_SENTINEL) {
            global.regexp = global.getBuiltinRegExp();
        }
        return global.regexp;
    }

    /**
     * Setter for ECMA 15.1.4.8 RegExp property
     *
     * @param self self reference
     * @param value value for the RegExp property
     */
    @Setter(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
    public static void setRegExp(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.regexp = value;
    }

    private volatile Object regexp = LAZY_SENTINEL;

    /**
     * Getter for ECMA 15.12 - The JSON property
     * @param self self reference
     * @return the value of JSON property
     */
    @Getter(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getJSON(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.json == LAZY_SENTINEL) {
            global.json = global.getBuiltinJSON();
        }
        return global.json;
    }

    /**
     * Setter for ECMA 15.12 - The JSON property
     * @param self self reference
     * @param value value for the JSON property
     */
    @Setter(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
    public static void setJSON(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.json = value;
    }

    private volatile Object json = LAZY_SENTINEL;

    /**
     * Getter for Nashorn extension: global.JSAdapter
     * @param self self reference
     * @return value of the JSAdapter property
     */
    @Getter(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getJSAdapter(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.jsadapter == LAZY_SENTINEL) {
            global.jsadapter = global.getBuiltinJSAdapter();
        }
        return global.jsadapter;
    }

    /**
     * Setter for Nashorn extension: global.JSAdapter
     * @param self self reference
     * @param value value for the JSAdapter property
     */
    @Setter(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
    public static void setJSAdapter(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.jsadapter = value;
    }

    private volatile Object jsadapter = LAZY_SENTINEL;

    /** ECMA 15.8 - The Math object */
    @Property(name = "Math", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object math;

    /** Error object */
    @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object error;

    /**
     * Getter for the EvalError property
     * @param self self reference
     * @return the value of EvalError property
     */
    @Getter(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getEvalError(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.evalError == LAZY_SENTINEL) {
            global.evalError = global.getBuiltinEvalError();
        }
        return global.evalError;
    }

    /**
     * Setter for the EvalError property
     * @param self self reference
     * @param value value of the EvalError property
     */
    @Setter(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
    public static void setEvalError(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.evalError = value;
    }

    private volatile Object evalError = LAZY_SENTINEL;

    /**
     * Getter for the RangeError property.
     * @param self self reference
     * @return the value of RangeError property
     */
    @Getter(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getRangeError(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.rangeError == LAZY_SENTINEL) {
            global.rangeError = global.getBuiltinRangeError();
        }
        return global.rangeError;
    }


    /**
     * Setter for the RangeError property.
     * @param self self reference
     * @param value value for the RangeError property
     */
    @Setter(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
    public static void setRangeError(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.rangeError = value;
    }

    private volatile Object rangeError = LAZY_SENTINEL;

    /** ReferenceError object */
    @Property(name = "ReferenceError", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object referenceError;

    /** SyntaxError object */
    @Property(name = "SyntaxError", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object syntaxError;

    /** TypeError object */
    @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object typeError;

    /**
     * Getter for the URIError property.
     * @param self self reference
     * @return the value of URIError property
     */
    @Getter(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getURIError(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.uriError == LAZY_SENTINEL) {
            global.uriError = global.getBuiltinURIError();
        }
        return global.uriError;
    }

    /**
     * Setter for the URIError property.
     * @param self self reference
     * @param value value for the URIError property
     */
    @Setter(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
    public static void setURIError(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.uriError = value;
    }

    private volatile Object uriError = LAZY_SENTINEL;

    /**
     * Getter for the ArrayBuffer property.
     * @param self self reference
     * @return the value of the ArrayBuffer property
     */
    @Getter(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getArrayBuffer(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.arrayBuffer == LAZY_SENTINEL) {
            global.arrayBuffer = global.getBuiltinArrayBuffer();
        }
        return global.arrayBuffer;
    }

    /**
     * Setter for the ArrayBuffer property.
     * @param self self reference
     * @param value value of the ArrayBuffer property
     */
    @Setter(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
    public static void setArrayBuffer(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.arrayBuffer = value;
    }

    private volatile Object arrayBuffer;

    /**
     * Getter for the DataView property.
     * @param self self reference
     * @return the value of the DataView property
     */
    @Getter(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getDataView(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.dataView == LAZY_SENTINEL) {
            global.dataView = global.getBuiltinDataView();
        }
        return global.dataView;
    }


    /**
     * Setter for the DataView property.
     * @param self self reference
     * @param value value of the DataView property
     */
    @Setter(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
    public static void setDataView(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.dataView = value;
    }

    private volatile Object dataView;

    /**
     * Getter for the Int8Array property.
     * @param self self reference
     * @return the value of the Int8Array property.
     */
    @Getter(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getInt8Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.int8Array == LAZY_SENTINEL) {
            global.int8Array = global.getBuiltinInt8Array();
        }
        return global.int8Array;
    }

    /**
     * Setter for the Int8Array property.
     * @param self self reference
     * @param value value of the Int8Array property
     */
    @Setter(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setInt8Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.int8Array = value;
    }

    private volatile Object int8Array;

    /**
     * Getter for the Uin8Array property.
     * @param self self reference
     * @return the value of the Uint8Array property
     */
    @Getter(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getUint8Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.uint8Array == LAZY_SENTINEL) {
            global.uint8Array = global.getBuiltinUint8Array();
        }
        return global.uint8Array;
    }

    /**
     * Setter for the Uin8Array property.
     * @param self self reference
     * @param value value of the Uin8Array property
     */
    @Setter(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setUint8Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.uint8Array = value;
    }

    private volatile Object uint8Array;

    /**
     * Getter for the Uint8ClampedArray property.
     * @param self self reference
     * @return the value of the Uint8ClampedArray property
     */
    @Getter(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getUint8ClampedArray(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.uint8ClampedArray == LAZY_SENTINEL) {
            global.uint8ClampedArray = global.getBuiltinUint8ClampedArray();
        }
        return global.uint8ClampedArray;
    }

    /**
     * Setter for the Uint8ClampedArray property.
     * @param self self reference
     * @param value value of the Uint8ClampedArray property
     */
    @Setter(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
    public static void setUint8ClampedArray(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.uint8ClampedArray = value;
    }

    private volatile Object uint8ClampedArray;

    /**
     * Getter for the Int16Array property.
     * @param self self reference
     * @return the value of the Int16Array property
     */
    @Getter(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getInt16Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.int16Array == LAZY_SENTINEL) {
            global.int16Array = global.getBuiltinInt16Array();
        }
        return global.int16Array;
    }

    /**
     * Setter for the Int16Array property.
     * @param self self reference
     * @param value value of the Int16Array property
     */
    @Setter(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setInt16Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.int16Array = value;
    }

    private volatile Object int16Array;

    /**
     * Getter for the Uint16Array property.
     * @param self self reference
     * @return the value of the Uint16Array property
     */
    @Getter(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getUint16Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.uint16Array == LAZY_SENTINEL) {
            global.uint16Array = global.getBuiltinUint16Array();
        }
        return global.uint16Array;
    }

    /**
     * Setter for the Uint16Array property.
     * @param self self reference
     * @param value value of the Uint16Array property
     */
    @Setter(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setUint16Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.uint16Array = value;
    }

    private volatile Object uint16Array;

    /**
     * Getter for the Int32Array property.
     *
     * @param self self reference
     * @return the value of the Int32Array property
     */
    @Getter(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getInt32Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.int32Array == LAZY_SENTINEL) {
            global.int32Array = global.getBuiltinInt32Array();
        }
        return global.int32Array;
    }


    /**
     * Setter for the Int32Array property.
     *
     * @param self self reference
     * @param value value of the Int32Array property
     */
    @Setter(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setInt32Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.int32Array = value;
    }

    private volatile Object int32Array;

    /**
     * Getter of the Uint32Array property.
     *
     * @param self self reference
     * @return the value of the Uint32Array property
     */
    @Getter(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getUint32Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.uint32Array == LAZY_SENTINEL) {
            global.uint32Array = global.getBuiltinUint32Array();
        }
        return global.uint32Array;
    }


    /**
     * Setter of the Uint32Array property.
     *
     * @param self self reference
     * @param value value of the Uint32Array property
     */
    @Setter(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setUint32Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.uint32Array = value;
    }

    private volatile Object uint32Array;

    /**
     * Getter for the Float32Array property.
     *
     * @param self self reference
     * @return the value of the Float32Array property
     */
    @Getter(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getFloat32Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.float32Array == LAZY_SENTINEL) {
            global.float32Array = global.getBuiltinFloat32Array();
        }
        return global.float32Array;
    }

    /**
     * Setter for the Float32Array property.
     *
     * @param self self reference
     * @param value value of the Float32Array property
     */
    @Setter(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setFloat32Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.float32Array = value;
    }

    private volatile Object float32Array;

    /**
     * Getter for the Float64Array property.
     *
     * @param self self reference
     * @return the value of the Float64Array property
     */
    @Getter(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getFloat64Array(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.float64Array == LAZY_SENTINEL) {
            global.float64Array = global.getBuiltinFloat64Array();
        }
        return global.float64Array;
    }

    /**
     * Setter for the Float64Array property.
     *
     * @param self self reference
     * @param value value of the Float64Array property
     */
    @Setter(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
    public static void setFloat64Array(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.float64Array = value;
    }

    private volatile Object float64Array;

    /** Nashorn extension: Java access - global.Packages */
    @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object packages;

    /** Nashorn extension: Java access - global.com */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object com;

    /** Nashorn extension: Java access - global.edu */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object edu;

    /** Nashorn extension: Java access - global.java */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object java;

    /** Nashorn extension: Java access - global.javafx */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object javafx;

    /** Nashorn extension: Java access - global.javax */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object javax;

    /** Nashorn extension: Java access - global.org */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object org;

    /**
     * Getter for the Nashorn extension: Java access - global.javaImporter.
     *
     * @param self self reference
     * @return the value of the JavaImporter property
     */
    @Getter(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getJavaImporter(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.javaImporter == LAZY_SENTINEL) {
            global.javaImporter = global.getBuiltinJavaImporter();
        }
        return global.javaImporter;
    }

    /**
     * Setter for the Nashorn extension: Java access - global.javaImporter.
     *
     * @param self self reference
     * @param value value of the JavaImporter property
     */
    @Setter(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
    public static void setJavaImporter(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.javaImporter = value;
    }

    private volatile Object javaImporter;

    /**
     * Getter for the Nashorn extension: global.Java property.
     *
     * @param self self reference
     * @return the value of the Java property
     */
    @Getter(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
    public static Object getJavaApi(final Object self) {
        final Global global = Global.instanceFrom(self);
        if (global.javaApi == LAZY_SENTINEL) {
            global.javaApi = global.getBuiltinJavaApi();
        }
        return global.javaApi;
    }

    /**
     * Setter for the Nashorn extension: global.Java property.
     *
     * @param self self reference
     * @param value value of the Java property
     */
    @Setter(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
    public static void setJavaApi(final Object self, final Object value) {
        final Global global = Global.instanceFrom(self);
        global.javaApi = value;
    }

    private volatile Object javaApi;

    /** Nashorn extension: current script's file name */
    @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final Object __FILE__ = LAZY_SENTINEL;

    /** Nashorn extension: current script's directory */
    @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final Object __DIR__ = LAZY_SENTINEL;

    /** Nashorn extension: current source line number being executed */
    @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public static final Object __LINE__ = LAZY_SENTINEL;

    private volatile NativeDate DEFAULT_DATE;

    /** Used as Date.prototype's default value */
    NativeDate getDefaultDate() {
        return DEFAULT_DATE;
    }

    private volatile NativeRegExp DEFAULT_REGEXP;

    /** Used as RegExp.prototype's default value */
    NativeRegExp getDefaultRegExp() {
        return DEFAULT_REGEXP;
    }

    /*
     * Built-in constructor objects: Even if user changes dynamic values of
     * "Object", "Array" etc., we still want to keep original values of these
     * constructors here. For example, we need to be able to create array,
     * regexp literals even after user overwrites global "Array" or "RegExp"
     * constructor - see also ECMA 262 spec. Annex D.
     */
    private ScriptFunction builtinFunction;
    private ScriptFunction builtinObject;
    private ScriptFunction builtinArray;
    private ScriptFunction builtinBoolean;
    private ScriptFunction builtinDate;
    private ScriptObject   builtinJSON;
    private ScriptFunction builtinJSAdapter;
    private ScriptObject   builtinMath;
    private ScriptFunction builtinNumber;
    private ScriptFunction builtinRegExp;
    private ScriptFunction builtinString;
    private ScriptFunction builtinError;
    private ScriptFunction builtinEval;
    private ScriptFunction builtinEvalError;
    private ScriptFunction builtinRangeError;
    private ScriptFunction builtinReferenceError;
    private ScriptFunction builtinSyntaxError;
    private ScriptFunction builtinTypeError;
    private ScriptFunction builtinURIError;
    private ScriptObject   builtinPackages;
    private ScriptObject   builtinCom;
    private ScriptObject   builtinEdu;
    private ScriptObject   builtinJava;
    private ScriptObject   builtinJavafx;
    private ScriptObject   builtinJavax;
    private ScriptObject   builtinOrg;
    private ScriptFunction builtinJavaImporter;
    private ScriptObject   builtinJavaApi;
    private ScriptFunction builtinArrayBuffer;
    private ScriptFunction builtinDataView;
    private ScriptFunction builtinInt8Array;
    private ScriptFunction builtinUint8Array;
    private ScriptFunction builtinUint8ClampedArray;
    private ScriptFunction builtinInt16Array;
    private ScriptFunction builtinUint16Array;
    private ScriptFunction builtinInt32Array;
    private ScriptFunction builtinUint32Array;
    private ScriptFunction builtinFloat32Array;
    private ScriptFunction builtinFloat64Array;

    /*
     * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
     */
    private ScriptFunction typeErrorThrower;

    // Used to store the last RegExp result to support deprecated RegExp constructor properties
    private RegExpResult lastRegExpResult;

    private static final MethodHandle EVAL                 = findOwnMH_S("eval",                Object.class, Object.class, Object.class);
    private static final MethodHandle NO_SUCH_PROPERTY     = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
    private static final MethodHandle PRINT                = findOwnMH_S("print",               Object.class, Object.class, Object[].class);
    private static final MethodHandle PRINTLN              = findOwnMH_S("println",             Object.class, Object.class, Object[].class);
    private static final MethodHandle LOAD                 = findOwnMH_S("load",                Object.class, Object.class, Object.class);
    private static final MethodHandle LOAD_WITH_NEW_GLOBAL = findOwnMH_S("loadWithNewGlobal",   Object.class, Object.class, Object[].class);
    private static final MethodHandle EXIT                 = findOwnMH_S("exit",                Object.class, Object.class, Object.class);
    private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter",  Object.class, Object.class);

    // initialized by nasgen
    private static PropertyMap $nasgenmap$;

    // context to which this global belongs to
    private final Context context;

    // current ScriptContext to use - can be null.
    private ThreadLocal<ScriptContext> scontext;
    // current ScriptEngine associated - can be null.
    private ScriptEngine engine;

    // ES6 global lexical scope.
    private final LexicalScope lexicalScope;

    // Switchpoint for non-constant global callsites in the presence of ES6 lexical scope.
    private SwitchPoint lexicalScopeSwitchPoint;

    /**
     * Set the current script context
     * @param ctxt script context
     */
    public void setScriptContext(final ScriptContext ctxt) {
        assert scontext != null;
        scontext.set(ctxt);
    }

    /**
     * Get the current script context
     * @return current script context
     */
    public ScriptContext getScriptContext() {
        assert scontext != null;
        return scontext.get();
    }

    private ScriptContext currentContext() {
        final ScriptContext sc = scontext != null? scontext.get() : null;
        return (sc != null)? sc : (engine != null? engine.getContext() : null);
    }

    @Override
    protected Context getContext() {
        return context;
    }

    @Override
    protected boolean useDualFields() {
        return context.useDualFields();
    }

    // performs initialization checks for Global constructor and returns the
    // PropertyMap, if everything is fine.
    private static PropertyMap checkAndGetMap(final Context context) {
        // security check first
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
        }

        Objects.requireNonNull(context);

        return $nasgenmap$;
    }

    /**
     * Constructor
     *
     * @param context the context
     */
    public Global(final Context context) {
        super(checkAndGetMap(context));
        this.context = context;
        this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
    }

    /**
     * Script access to "current" Global instance
     *
     * @return the global singleton
     */
    public static Global instance() {
        return Objects.requireNonNull(Context.getGlobal());
    }

    private static Global instanceFrom(final Object self) {
        return self instanceof Global? (Global)self : instance();
    }

    /**
     * Check if we have a Global instance
     * @return true if one exists
     */
    public static boolean hasInstance() {
        return Context.getGlobal() != null;
    }

    /**
     * Script access to {@link ScriptEnvironment}
     *
     * @return the script environment
     */
    static ScriptEnvironment getEnv() {
        return instance().getContext().getEnv();
    }

    /**
     * Script access to {@link Context}
     *
     * @return the context
     */
    static Context getThisContext() {
        return instance().getContext();
    }

    // Runtime interface to Global

    /**
     * Is there a class filter in the current Context?
     * @return class filter
     */
    public ClassFilter getClassFilter() {
        return context.getClassFilter();
    }

    /**
     * Is this global of the given Context?
     * @param ctxt the context
     * @return true if this global belongs to the given Context
     */
    public boolean isOfContext(final Context ctxt) {
        return this.context == ctxt;
    }

    /**
     * Does this global belong to a strict Context?
     * @return true if this global belongs to a strict Context
     */
    public boolean isStrictContext() {
        return context.getEnv()._strict;
    }

    /**
     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
     * of the global scope object.
     *
     * @param eng ScriptEngine to initialize
     */
    public void initBuiltinObjects(final ScriptEngine eng) {
        if (this.builtinObject != null) {
            // already initialized, just return
            return;
        }

        this.engine = eng;
        if (this.engine != null) {
            this.scontext = new ThreadLocal<>();
        }
        init(eng);
    }

    /**
     * Wrap a Java object as corresponding script object
     *
     * @param obj object to wrap
     * @return    wrapped object
     */
    public Object wrapAsObject(final Object obj) {
        if (obj instanceof Boolean) {
            return new NativeBoolean((Boolean)obj, this);
        } else if (obj instanceof Number) {
            return new NativeNumber(((Number)obj).doubleValue(), this);
        } else if (isString(obj)) {
            return new NativeString((CharSequence)obj, this);
        } else if (obj instanceof Object[]) { // extension
            return new NativeArray(ArrayData.allocate((Object[])obj), this);
        } else if (obj instanceof double[]) { // extension
            return new NativeArray(ArrayData.allocate((double[])obj), this);
        } else if (obj instanceof int[]) {
            return new NativeArray(ArrayData.allocate((int[]) obj), this);
        } else if (obj instanceof ArrayData) {
            return new NativeArray((ArrayData) obj, this);
        } else {
            // FIXME: more special cases? Map? List?
            return obj;
        }
    }

    /**
     * Lookup helper for JS primitive types
     *
     * @param request the link request for the dynamic call site.
     * @param self     self reference
     *
     * @return guarded invocation
     */
    public static GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
        if (isString(self)) {
            return NativeString.lookupPrimitive(request, self);
        } else if (self instanceof Number) {
            return NativeNumber.lookupPrimitive(request, self);
        } else if (self instanceof Boolean) {
            return NativeBoolean.lookupPrimitive(request, self);
        }
        throw new IllegalArgumentException("Unsupported primitive: " + self);
    }

    /**
     * Returns a method handle that creates a wrapper object for a JS primitive value.
     *
     * @param self receiver object
     * @return method handle to create wrapper objects for primitive receiver
     */
    public static MethodHandle getPrimitiveWrapFilter(final Object self) {
        if (isString(self)) {
            return NativeString.WRAPFILTER;
        } else if (self instanceof Number) {
            return NativeNumber.WRAPFILTER;
        } else if (self instanceof Boolean) {
            return NativeBoolean.WRAPFILTER;
        }
        throw new IllegalArgumentException("Unsupported primitive: " + self);
    }


    /**
     * Create a new empty script object
     *
     * @return the new ScriptObject
     */
    public ScriptObject newObject() {
        return useDualFields() ? new JD(getObjectPrototype()) : new JO(getObjectPrototype());
    }

    /**
     * Default value of given type
     *
     * @param sobj     script object
     * @param typeHint type hint
     *
     * @return default value
     */
    public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
        // When the [[DefaultValue]] internal method of O is called with no hint,
        // then it behaves as if the hint were Number, unless O is a Date object
        // in which case it behaves as if the hint were String.
        Class<?> hint = typeHint;
        if (hint == null) {
            hint = Number.class;
        }

        try {
            if (hint == String.class) {

                final Object toString = TO_STRING.getGetter().invokeExact(sobj);

                if (Bootstrap.isCallable(toString)) {
                    final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
                    if (JSType.isPrimitive(value)) {
                        return value;
                    }
                }

                final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
                if (Bootstrap.isCallable(valueOf)) {
                    final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
                    if (JSType.isPrimitive(value)) {
                        return value;
                    }
                }
                throw typeError(this, "cannot.get.default.string");
            }

            if (hint == Number.class) {
                final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
                if (Bootstrap.isCallable(valueOf)) {
                    final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
                    if (JSType.isPrimitive(value)) {
                        return value;
                    }
                }

                final Object toString = TO_STRING.getGetter().invokeExact(sobj);
                if (Bootstrap.isCallable(toString)) {
                    final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
                    if (JSType.isPrimitive(value)) {
                        return value;
                    }
                }

                throw typeError(this, "cannot.get.default.number");
            }
        } catch (final RuntimeException | Error e) {
            throw e;
        } catch (final Throwable t) {
            throw new RuntimeException(t);
        }

        return UNDEFINED;
    }

    /**
     * Is the given ScriptObject an ECMAScript Error object?
     *
     * @param sobj the object being checked
     * @return true if sobj is an Error object
     */
    public boolean isError(final ScriptObject sobj) {
        final ScriptObject errorProto = getErrorPrototype();
        ScriptObject proto = sobj.getProto();
        while (proto != null) {
            if (proto == errorProto) {
                return true;
            }
            proto = proto.getProto();
        }
        return false;
    }

    /**
     * Create a new ECMAScript Error object.
     *
     * @param msg error message
     * @return newly created Error object
     */
    public ScriptObject newError(final String msg) {
        return new NativeError(msg, this);
    }

    /**
     * Create a new ECMAScript EvalError object.
     *
     * @param msg error message
     * @return newly created EvalError object
     */
    public ScriptObject newEvalError(final String msg) {
        return new NativeEvalError(msg, this);
    }

    /**
     * Create a new ECMAScript RangeError object.
     *
     * @param msg error message
     * @return newly created RangeError object
     */
    public ScriptObject newRangeError(final String msg) {
        return new NativeRangeError(msg, this);
    }

    /**
     * Create a new ECMAScript ReferenceError object.
     *
     * @param msg error message
     * @return newly created ReferenceError object
     */
    public ScriptObject newReferenceError(final String msg) {
        return new NativeReferenceError(msg, this);
    }

    /**
     * Create a new ECMAScript SyntaxError object.
     *
     * @param msg error message
     * @return newly created SyntaxError object
     */
    public ScriptObject newSyntaxError(final String msg) {
        return new NativeSyntaxError(msg, this);
    }

    /**
     * Create a new ECMAScript TypeError object.
     *
     * @param msg error message
     * @return newly created TypeError object
     */
    public ScriptObject newTypeError(final String msg) {
        return new NativeTypeError(msg, this);
    }

    /**
     * Create a new ECMAScript URIError object.
     *
     * @param msg error message
     * @return newly created URIError object
     */
    public ScriptObject newURIError(final String msg) {
        return new NativeURIError(msg, this);
    }

    /**
     * Create a new ECMAScript GenericDescriptor object.
     *
     * @param configurable is the property configurable?
     * @param enumerable is the property enumerable?
     * @return newly created GenericDescriptor object
     */
    public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
        return new GenericPropertyDescriptor(configurable, enumerable, this);
    }

    /**
     * Create a new ECMAScript DatePropertyDescriptor object.
     *
     * @param value of the data property
     * @param configurable is the property configurable?
     * @param enumerable is the property enumerable?
     * @param writable is the property writable?
     * @return newly created DataPropertyDescriptor object
     */
    public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
        return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
    }

    /**
     * Create a new ECMAScript AccessorPropertyDescriptor object.
     *
     * @param get getter function of the user accessor property
     * @param set setter function of the user accessor property
     * @param configurable is the property configurable?
     * @param enumerable is the property enumerable?
     * @return newly created AccessorPropertyDescriptor object
     */
    public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
        final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);

        if (get == null) {
            desc.delete(PropertyDescriptor.GET, false);
        }

        if (set == null) {
            desc.delete(PropertyDescriptor.SET, false);
        }

        return desc;
    }

    private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
        final T obj = map.get(key);
        if (obj != null) {
            return obj;
        }

        try {
            final T newObj = creator.call();
            final T existingObj = map.putIfAbsent(key, newObj);
            return existingObj != null ? existingObj : newObj;
        } catch (final Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();


    /**
     * Get cached InvokeByName object for the given key
     * @param key key to be associated with InvokeByName object
     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
     * @return InvokeByName object associated with the key.
     */
    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
        return getLazilyCreatedValue(key, creator, namedInvokers);
    }

    private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();

    /**
     * Get cached dynamic method handle for the given key
     * @param key key to be associated with dynamic method handle
     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
     * @return dynamic method handle associated with the key.
     */
    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
        return getLazilyCreatedValue(key, creator, dynamicInvokers);
    }

    /**
     * Hook to search missing variables in ScriptContext if available
     * @param self used to detect if scope call or not (this function is 'strict')
     * @param name name of the variable missing
     * @return value of the missing variable or undefined (or TypeError for scope search)
     */
    public static Object __noSuchProperty__(final Object self, final Object name) {
        final Global global = Global.instance();
        final ScriptContext sctxt = global.currentContext();
        final String nameStr = name.toString();

        if (sctxt != null) {
            final int scope = sctxt.getAttributesScope(nameStr);
            if (scope != -1) {
                return ScriptObjectMirror.unwrap(sctxt.getAttribute(nameStr, scope), global);
            }
        }

        switch (nameStr) {
        case "context":
            return sctxt;
        case "engine":
            return global.engine;
        default:
            break;
        }

        if (self == UNDEFINED) {
            // scope access and so throw ReferenceError
            throw referenceError(global, "not.defined", nameStr);
        }

        return UNDEFINED;
    }

    /**
     * This is the eval used when 'indirect' eval call is made.
     *
     * var global = this;
     * global.eval("print('hello')");
     *
     * @param self  eval scope
     * @param str   eval string
     *
     * @return the result of eval
     */
    public static Object eval(final Object self, final Object str) {
        return directEval(self, str, Global.instanceFrom(self), UNDEFINED, false);
    }

    /**
     * Direct eval
     *
     * @param self     The scope of eval passed as 'self'
     * @param str      Evaluated code
     * @param callThis "this" to be passed to the evaluated code
     * @param location location of the eval call
     * @param strict   is eval called from a strict mode code?
     *
     * @return the return value of the eval
     *
     * This is directly invoked from generated when eval(code) is called in user code
     */
    public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final boolean strict) {
        if (!isString(str)) {
            return str;
        }
        final Global global = Global.instanceFrom(self);
        final ScriptObject scope = self instanceof ScriptObject && ((ScriptObject)self).isScope() ? (ScriptObject)self : global;

        return global.getContext().eval(scope, str.toString(), callThis, location, strict, true);
    }

    /**
     * Global print implementation - Nashorn extension
     *
     * @param self    scope
     * @param objects arguments to print
     *
     * @return result of print (undefined)
     */
    public static Object print(final Object self, final Object... objects) {
        return Global.instanceFrom(self).printImpl(false, objects);
    }

    /**
     * Global println implementation - Nashorn extension
     *
     * @param self    scope
     * @param objects arguments to print
     *
     * @return result of println (undefined)
     */
    public static Object println(final Object self, final Object... objects) {
        return Global.instanceFrom(self).printImpl(true, objects);
    }

    /**
     * Global load implementation - Nashorn extension.
     *
     * <p>
     * load builtin loads the given script. Script source can be a URL or a File
     * or a script object with name and script properties. Evaluated code gets
     * global object "this" and uses global object as scope for evaluation.
     * </p>
     * <p>
     * If self is undefined or null or global, then global object is used
     * as scope as well as "this" for the evaluated code. If self is any other
     * object, then it is indirect load call. With indirect load call, the
     * properties of scope are available to evaluated script as variables. Also,
     * global scope properties are accessible. Any var, function definition in
     * evaluated script goes into an object that is not accessible to user scripts.
     * </p>
     * Thus the indirect load call is equivalent to the following:
     * <pre>
     * <code>
     * (function (scope, source) {
     *    with(scope) {
     *        eval(&lt;script_from_source&gt;);
     *    }
     * })(self, source);
     * </code>
     * </pre>
     *
     * @param self    scope to use for the script evaluation
     * @param source  script source
     *
     * @return result of load (may be undefined)
     *
     * @throws IOException if source could not be read
     */
    public static Object load(final Object self, final Object source) throws IOException {
        final Global global = Global.instanceFrom(self);
        return global.getContext().load(self, source);
    }

    /**
     * Global loadWithNewGlobal implementation - Nashorn extension.
     *
     * loadWithNewGlobal builtin loads the given script from a URL or a File
     * or a script object with name and script properties. Evaluated code gets
     * new global object "this" and uses that new global object as scope for evaluation.
     *
     * @param self self This value is ignored by this function
     * @param args optional arguments to be passed to the loaded script
     *
     * @return result of load (may be undefined)
     *
     * @throws IOException if source could not be read
     */
    public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
        final Global global = Global.instanceFrom(self);
        final int length = args.length;
        final boolean hasArgs = 0 < length;
        final Object from = hasArgs ? args[0] : UNDEFINED;
        final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;

        return global.getContext().loadWithNewGlobal(from, arguments);
    }

    /**
     * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script
     *
     * @param self  self reference
     * @param code  exit code
     *
     * @return undefined (will never be reached)
     */
    public static Object exit(final Object self, final Object code) {
        System.exit(JSType.toInt32(code));
        return UNDEFINED;
    }

    // builtin prototype accessors

    /**
     * Get the builtin Object prototype.
     * @return the object prototype.
     */
    public ScriptObject getObjectPrototype() {
        return ScriptFunction.getPrototype(builtinObject);
    }

    /**
     * Get the builtin Function prototype.
     * @return the Function.prototype.
     */
    public ScriptObject getFunctionPrototype() {
        return ScriptFunction.getPrototype(builtinFunction);
    }

    ScriptObject getArrayPrototype() {
        return ScriptFunction.getPrototype(builtinArray);
    }

    ScriptObject getBooleanPrototype() {
        return ScriptFunction.getPrototype(builtinBoolean);
    }

    ScriptObject getNumberPrototype() {
        return ScriptFunction.getPrototype(builtinNumber);
    }

    ScriptObject getDatePrototype() {
        return ScriptFunction.getPrototype(getBuiltinDate());
    }

    ScriptObject getRegExpPrototype() {
        return ScriptFunction.getPrototype(getBuiltinRegExp());
    }

    ScriptObject getStringPrototype() {
        return ScriptFunction.getPrototype(builtinString);
    }

    ScriptObject getErrorPrototype() {
        return ScriptFunction.getPrototype(builtinError);
    }

    ScriptObject getEvalErrorPrototype() {
        return ScriptFunction.getPrototype(getBuiltinEvalError());
    }

    ScriptObject getRangeErrorPrototype() {
        return ScriptFunction.getPrototype(getBuiltinRangeError());
    }

    ScriptObject getReferenceErrorPrototype() {
        return ScriptFunction.getPrototype(builtinReferenceError);
    }

    ScriptObject getSyntaxErrorPrototype() {
        return ScriptFunction.getPrototype(builtinSyntaxError);
    }

    ScriptObject getTypeErrorPrototype() {
        return ScriptFunction.getPrototype(builtinTypeError);
    }

    ScriptObject getURIErrorPrototype() {
        return ScriptFunction.getPrototype(getBuiltinURIError());
    }

    ScriptObject getJavaImporterPrototype() {
        return ScriptFunction.getPrototype(getBuiltinJavaImporter());
    }

    ScriptObject getJSAdapterPrototype() {
        return ScriptFunction.getPrototype(getBuiltinJSAdapter());
    }

    private synchronized ScriptFunction getBuiltinArrayBuffer() {
        if (this.builtinArrayBuffer == null) {
            this.builtinArrayBuffer = initConstructorAndSwitchPoint("ArrayBuffer", ScriptFunction.class);
        }
        return this.builtinArrayBuffer;
    }

    ScriptObject getArrayBufferPrototype() {
        return ScriptFunction.getPrototype(getBuiltinArrayBuffer());
    }

    private synchronized ScriptFunction getBuiltinDataView() {
        if (this.builtinDataView == null) {
            this.builtinDataView = initConstructorAndSwitchPoint("DataView", ScriptFunction.class);
        }
        return this.builtinDataView;
    }

    ScriptObject getDataViewPrototype() {
        return ScriptFunction.getPrototype(getBuiltinDataView());
    }

    private synchronized ScriptFunction getBuiltinInt8Array() {
        if (this.builtinInt8Array == null) {
            this.builtinInt8Array = initConstructorAndSwitchPoint("Int8Array", ScriptFunction.class);
        }
        return this.builtinInt8Array;
    }

    ScriptObject getInt8ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinInt8Array());
    }

    private synchronized ScriptFunction getBuiltinUint8Array() {
        if (this.builtinUint8Array == null) {
            this.builtinUint8Array = initConstructorAndSwitchPoint("Uint8Array", ScriptFunction.class);
        }
        return this.builtinUint8Array;
    }

    ScriptObject getUint8ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinUint8Array());
    }

    private synchronized ScriptFunction getBuiltinUint8ClampedArray() {
        if (this.builtinUint8ClampedArray == null) {
            this.builtinUint8ClampedArray = initConstructorAndSwitchPoint("Uint8ClampedArray", ScriptFunction.class);
        }
        return this.builtinUint8ClampedArray;
    }

    ScriptObject getUint8ClampedArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinUint8ClampedArray());
    }

    private synchronized ScriptFunction getBuiltinInt16Array() {
        if (this.builtinInt16Array == null) {
            this.builtinInt16Array = initConstructorAndSwitchPoint("Int16Array", ScriptFunction.class);
        }
        return this.builtinInt16Array;
    }

    ScriptObject getInt16ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinInt16Array());
    }

    private synchronized ScriptFunction getBuiltinUint16Array() {
        if (this.builtinUint16Array == null) {
            this.builtinUint16Array = initConstructorAndSwitchPoint("Uint16Array", ScriptFunction.class);
        }
        return this.builtinUint16Array;
    }

    ScriptObject getUint16ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinUint16Array());
    }

    private synchronized ScriptFunction getBuiltinInt32Array() {
        if (this.builtinInt32Array == null) {
            this.builtinInt32Array = initConstructorAndSwitchPoint("Int32Array", ScriptFunction.class);
        }
        return this.builtinInt32Array;
    }

    ScriptObject getInt32ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinInt32Array());
    }

    private synchronized ScriptFunction getBuiltinUint32Array() {
        if (this.builtinUint32Array == null) {
            this.builtinUint32Array = initConstructorAndSwitchPoint("Uint32Array", ScriptFunction.class);
        }
        return this.builtinUint32Array;
    }

    ScriptObject getUint32ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinUint32Array());
    }

    private synchronized ScriptFunction getBuiltinFloat32Array() {
        if (this.builtinFloat32Array == null) {
            this.builtinFloat32Array = initConstructorAndSwitchPoint("Float32Array", ScriptFunction.class);
        }
        return this.builtinFloat32Array;
    }

    ScriptObject getFloat32ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinFloat32Array());
    }

    private synchronized ScriptFunction getBuiltinFloat64Array() {
        if (this.builtinFloat64Array == null) {
            this.builtinFloat64Array = initConstructorAndSwitchPoint("Float64Array", ScriptFunction.class);
        }
        return this.builtinFloat64Array;
    }

    ScriptObject getFloat64ArrayPrototype() {
        return ScriptFunction.getPrototype(getBuiltinFloat64Array());
    }

    /**
     * Return the function that throws TypeError unconditionally. Used as "poison" methods for certain Function properties.
     *
     * @return the TypeError throwing function
     */
    public ScriptFunction getTypeErrorThrower() {
        return typeErrorThrower;
    }

    private synchronized ScriptFunction getBuiltinDate() {
        if (this.builtinDate == null) {
            this.builtinDate = initConstructorAndSwitchPoint("Date", ScriptFunction.class);
            final ScriptObject dateProto = ScriptFunction.getPrototype(builtinDate);
            // initialize default date
            this.DEFAULT_DATE = new NativeDate(NaN, dateProto);
        }
        return this.builtinDate;
    }

    private synchronized ScriptFunction getBuiltinEvalError() {
        if (this.builtinEvalError == null) {
            this.builtinEvalError = initErrorSubtype("EvalError", getErrorPrototype());
        }
        return this.builtinEvalError;
    }

    private ScriptFunction getBuiltinFunction() {
        return builtinFunction;
    }

    /**
     * Get the switchpoint used to check property changes for Function.prototype.apply
     * @return the switchpoint guarding apply (same as guarding call, and everything else in function)
     */
    public static SwitchPoint getBuiltinFunctionApplySwitchPoint() {
        return ScriptFunction.getPrototype(Global.instance().getBuiltinFunction()).getProperty("apply").getBuiltinSwitchPoint();
    }

    private static boolean isBuiltinFunctionProperty(final String name) {
        final Global instance = Global.instance();
        final ScriptFunction builtinFunction = instance.getBuiltinFunction();
        if (builtinFunction == null) {
            return false; //conservative for compile-only mode
        }
        final boolean isBuiltinFunction = instance.function == builtinFunction;
        return isBuiltinFunction && ScriptFunction.getPrototype(builtinFunction).getProperty(name).isBuiltin();
    }

    /**
     * Check if the Function.prototype.apply has not been replaced
     * @return true if Function.prototype.apply has been replaced
     */
    public static boolean isBuiltinFunctionPrototypeApply() {
        return isBuiltinFunctionProperty("apply");
    }

    /**
     * Check if the Function.prototype.apply has not been replaced
     * @return true if Function.prototype.call has been replaced
     */
    public static boolean isBuiltinFunctionPrototypeCall() {
        return isBuiltinFunctionProperty("call");
    }

    private synchronized ScriptFunction getBuiltinJSAdapter() {
        if (this.builtinJSAdapter == null) {
            this.builtinJSAdapter = initConstructorAndSwitchPoint("JSAdapter", ScriptFunction.class);
        }
        return builtinJSAdapter;
    }

    private synchronized ScriptObject getBuiltinJSON() {
        if (this.builtinJSON == null) {
            this.builtinJSON = initConstructorAndSwitchPoint("JSON", ScriptObject.class);
        }
        return this.builtinJSON;
    }

    private synchronized ScriptFunction getBuiltinJavaImporter() {
        if (this.builtinJavaImporter == null) {
            this.builtinJavaImporter = initConstructor("JavaImporter", ScriptFunction.class);
        }
        return this.builtinJavaImporter;
    }

    private synchronized ScriptObject getBuiltinJavaApi() {
        if (this.builtinJavaApi == null) {
            this.builtinJavaApi = initConstructor("Java", ScriptObject.class);
        }
        return this.builtinJavaApi;
    }

    private synchronized ScriptFunction getBuiltinRangeError() {
        if (this.builtinRangeError == null) {
            this.builtinRangeError = initErrorSubtype("RangeError", getErrorPrototype());
        }
        return builtinRangeError;
    }

    private synchronized ScriptFunction getBuiltinRegExp() {
        if (this.builtinRegExp == null) {
            this.builtinRegExp = initConstructorAndSwitchPoint("RegExp", ScriptFunction.class);
            final ScriptObject regExpProto = ScriptFunction.getPrototype(builtinRegExp);
            // initialize default regexp object
            this.DEFAULT_REGEXP = new NativeRegExp("(?:)", "", this, regExpProto);
            // RegExp.prototype should behave like a RegExp object. So copy the
            // properties.
            regExpProto.addBoundProperties(DEFAULT_REGEXP);
        }
        return builtinRegExp;
    }

    private synchronized ScriptFunction getBuiltinURIError() {
        if (this.builtinURIError == null) {
            this.builtinURIError = initErrorSubtype("URIError", getErrorPrototype());
        }
        return this.builtinURIError;
    }

    @Override
    public String getClassName() {
        return "global";
    }

    /**
     * Copy function used to clone NativeRegExp objects.
     *
     * @param regexp a NativeRegExp to clone
     *
     * @return copy of the given regexp object
     */
    public static Object regExpCopy(final Object regexp) {
        return new NativeRegExp((NativeRegExp)regexp);
    }

    /**
     * Convert given object to NativeRegExp type.
     *
     * @param obj object to be converted
     * @return NativeRegExp instance
     */
    public static NativeRegExp toRegExp(final Object obj) {
        if (obj instanceof NativeRegExp) {
            return (NativeRegExp)obj;
        }
        return new NativeRegExp(JSType.toString(obj));
    }

    /**
     * ECMA 9.9 ToObject implementation
     *
     * @param obj  an item for which to run ToObject
     * @return ToObject version of given item
     */
    public static Object toObject(final Object obj) {
        if (obj == null || obj == UNDEFINED) {
            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
        }

        if (obj instanceof ScriptObject) {
            return obj;
        }

        return instance().wrapAsObject(obj);
    }

    /**
     * Allocate a new object array.
     *
     * @param initial object values.
     * @return the new array
     */
    public static NativeArray allocate(final Object[] initial) {
        ArrayData arrayData = ArrayData.allocate(initial);

        for (int index = 0; index < initial.length; index++) {
            final Object value = initial[index];

            if (value == ScriptRuntime.EMPTY) {
                arrayData = arrayData.delete(index);
            }
        }

        return new NativeArray(arrayData);
    }

    /**
     * Allocate a new number array.
     *
     * @param initial number values.
     * @return the new array
     */
    public static NativeArray allocate(final double[] initial) {
        return new NativeArray(ArrayData.allocate(initial));
    }

    /**
     * Allocate a new integer array.
     *
     * @param initial number values.
     * @return the new array
     */
    public static NativeArray allocate(final int[] initial) {
        return new NativeArray(ArrayData.allocate(initial));
    }

    /**
     * Allocate a new object array for arguments.
     *
     * @param arguments initial arguments passed.
     * @param callee reference to the function that uses arguments object
     * @param numParams actual number of declared parameters
     *
     * @return the new array
     */
    public static ScriptObject allocateArguments(final Object[] arguments, final Object callee, final int numParams) {
        return NativeArguments.allocate(arguments, (ScriptFunction)callee, numParams);
    }

    /**
     * Called from generated to check if given function is the builtin 'eval'. If
     * eval is used in a script, a lot of optimizations and assumptions cannot be done.
     *
     * @param  fn function object that is checked
     * @return true if fn is the builtin eval
     */
    public static boolean isEval(final Object fn) {
        return fn == Global.instance().builtinEval;
    }

    /**
     * Called from generated to replace a location property placeholder with the actual location property value.
     *
     * @param  placeholder the value tested for being a placeholder for a location property
     * @param  locationProperty the actual value for the location property
     * @return locationProperty if placeholder is indeed a placeholder for a location property, the placeholder otherwise
     */
    public static Object replaceLocationPropertyPlaceholder(final Object placeholder, final Object locationProperty) {
        return isLocationPropertyPlaceholder(placeholder) ? locationProperty : placeholder;
    }

    /**
     * Called from runtime internals to check if the passed value is a location property placeholder.
     * @param  placeholder the value tested for being a placeholder for a location property
     * @return true if the value is a placeholder, false otherwise.
     */
    public static boolean isLocationPropertyPlaceholder(final Object placeholder) {
        return placeholder == LAZY_SENTINEL;
    }

    /**
     * Create a new RegExp object.
     *
     * @param expression Regular expression.
     * @param options    Search options.
     *
     * @return New RegExp object.
     */
    public static Object newRegExp(final String expression, final String options) {
        if (options == null) {
            return new NativeRegExp(expression);
        }
        return new NativeRegExp(expression, options);
    }

    /**
     * Get the object prototype
     *
     * @return the object prototype
     */
    public static ScriptObject objectPrototype() {
        return Global.instance().getObjectPrototype();
    }

    /**
     * Create a new empty object instance.
     *
     * @return New empty object.
     */
    public static ScriptObject newEmptyInstance() {
        return Global.instance().newObject();
    }

    /**
     * Check if a given object is a ScriptObject, raises an exception if this is
     * not the case
     *
     * @param obj and object to check
     * @return the script object
     */
    public static ScriptObject checkObject(final Object obj) {
        if (!(obj instanceof ScriptObject)) {
            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
        }
        return (ScriptObject)obj;
    }

    /**
     * ECMA 9.10 - implementation of CheckObjectCoercible, i.e. raise an exception
     * if this object is null or undefined.
     *
     * @param obj an object to check
     */
    public static void checkObjectCoercible(final Object obj) {
        if (obj == null || obj == UNDEFINED) {
            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
        }
    }

    /**
     * Return the ES6 global scope for lexically declared bindings.
     * @return the ES6 lexical global scope.
     */
    public final ScriptObject getLexicalScope() {
        assert context.getEnv()._es6;
        return lexicalScope;
    }

    @Override
    public void addBoundProperties(final ScriptObject source, final jdk.nashorn.internal.runtime.Property[] properties) {
        PropertyMap ownMap = getMap();
        LexicalScope lexScope = null;
        PropertyMap lexicalMap = null;
        boolean hasLexicalDefinitions = false;

        if (context.getEnv()._es6) {
            lexScope = (LexicalScope) getLexicalScope();
            lexicalMap = lexScope.getMap();

            for (final jdk.nashorn.internal.runtime.Property property : properties) {
                if (property.isLexicalBinding()) {
                    hasLexicalDefinitions = true;
                }
                // ES6 15.1.8 steps 6. and 7.
                final jdk.nashorn.internal.runtime.Property globalProperty = ownMap.findProperty(property.getKey());
                if (globalProperty != null && !globalProperty.isConfigurable() && property.isLexicalBinding()) {
                    throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
                }
                final jdk.nashorn.internal.runtime.Property lexicalProperty = lexicalMap.findProperty(property.getKey());
                if (lexicalProperty != null && !property.isConfigurable()) {
                    throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
                }
            }
        }

        final boolean extensible = isExtensible();
        for (final jdk.nashorn.internal.runtime.Property property : properties) {
            if (property.isLexicalBinding()) {
                assert lexScope != null;
                lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property, true);

                if (ownMap.findProperty(property.getKey()) != null) {
                    // If property exists in the global object invalidate any global constant call sites.
                    invalidateGlobalConstant(property.getKey());
                }
            } else {
                ownMap = addBoundProperty(ownMap, source, property, extensible);
            }
        }

        setMap(ownMap);

        if (hasLexicalDefinitions) {
            assert lexScope != null;
            lexScope.setMap(lexicalMap);
            invalidateLexicalSwitchPoint();
        }
    }

    @Override
    public GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
        final boolean isScope = NashornCallSiteDescriptor.isScope(desc);

        if (lexicalScope != null && isScope && !NashornCallSiteDescriptor.isApplyToCall(desc)) {
            if (lexicalScope.hasOwnProperty(name)) {
                return lexicalScope.findGetMethod(desc, request, operator);
            }
        }

        final GuardedInvocation invocation =  super.findGetMethod(desc, request, operator);

        // We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
        // because those are invalidated per-key in the addBoundProperties method above.
        // We therefore check if the invocation does already have a switchpoint and the property is non-inherited,
        // assuming this only applies to global constants. If other non-inherited properties will
        // start using switchpoints some time in the future we'll have to revisit this.
        if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
            return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
        }

        return invocation;
    }

    @Override
    protected FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) {
        if (lexicalScope != null && start != this && start.isScope()) {
            final FindProperty find = lexicalScope.findProperty(key, false);
            if (find != null) {
                return find;
            }
        }
        return super.findProperty(key, deep, start);
    }

    @Override
    public GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
        final boolean isScope = NashornCallSiteDescriptor.isScope(desc);

        if (lexicalScope != null && isScope) {
            final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
            if (lexicalScope.hasOwnProperty(name)) {
                return lexicalScope.findSetMethod(desc, request);
            }
        }

        final GuardedInvocation invocation = super.findSetMethod(desc, request);

        if (isScope && context.getEnv()._es6) {
            return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
        }

        return invocation;
    }

    /**
     * Adds jjs shell interactive mode builtin functions to global scope.
     */
    public void addShellBuiltins() {
        Object value = ScriptFunction.createBuiltin("input", ShellFunctions.INPUT);
        addOwnProperty("input", Attribute.NOT_ENUMERABLE, value);

        value = ScriptFunction.createBuiltin("evalinput", ShellFunctions.EVALINPUT);
        addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value);
    }

    private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
        SwitchPoint switchPoint = lexicalScopeSwitchPoint;
        if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
            switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
        }
        return switchPoint;
    }

    private synchronized void invalidateLexicalSwitchPoint() {
        if (lexicalScopeSwitchPoint != null) {
            context.getLogger(GlobalConstants.class).info("Invalidating non-constant globals on lexical scope update");
            SwitchPoint.invalidateAll(new SwitchPoint[]{ lexicalScopeSwitchPoint });
        }
    }


    @SuppressWarnings("unused")
    private static Object lexicalScopeFilter(final Object self) {
        if (self instanceof Global) {
            return ((Global) self).getLexicalScope();
        }
        return self;
    }

    private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
        final T func = initConstructor(name, clazz);
        tagBuiltinProperties(name, func);
        return func;
    }

    @SuppressWarnings("hiding")
    private void init(final ScriptEngine eng) {
        assert Context.getGlobal() == this : "this global is not set as current";

        final ScriptEnvironment env = getContext().getEnv();

        // initialize Function and Object constructor
        initFunctionAndObject();

        // Now fix Global's own proto.
        this.setInitialProto(getObjectPrototype());

        // initialize global function properties
        this.eval = this.builtinEval = ScriptFunction.createBuiltin("eval", EVAL);

        this.parseInt = ScriptFunction.createBuiltin("parseInt",   GlobalFunctions.PARSEINT,
                    new Specialization[] {
                    new Specialization(GlobalFunctions.PARSEINT_Z),
                    new Specialization(GlobalFunctions.PARSEINT_I),
                    new Specialization(GlobalFunctions.PARSEINT_OI),
                    new Specialization(GlobalFunctions.PARSEINT_O) });
        this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
        this.isNaN = ScriptFunction.createBuiltin("isNaN",   GlobalFunctions.IS_NAN,
                   new Specialization[] {
                        new Specialization(GlobalFunctions.IS_NAN_I),
                        new Specialization(GlobalFunctions.IS_NAN_J),
                        new Specialization(GlobalFunctions.IS_NAN_D) });
        this.parseFloat         = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
        this.isNaN              = ScriptFunction.createBuiltin("isNaN",      GlobalFunctions.IS_NAN);
        this.isFinite           = ScriptFunction.createBuiltin("isFinite",   GlobalFunctions.IS_FINITE);
        this.encodeURI          = ScriptFunction.createBuiltin("encodeURI",  GlobalFunctions.ENCODE_URI);
        this.encodeURIComponent = ScriptFunction.createBuiltin("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
        this.decodeURI          = ScriptFunction.createBuiltin("decodeURI",  GlobalFunctions.DECODE_URI);
        this.decodeURIComponent = ScriptFunction.createBuiltin("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
        this.escape             = ScriptFunction.createBuiltin("escape",     GlobalFunctions.ESCAPE);
        this.unescape           = ScriptFunction.createBuiltin("unescape",   GlobalFunctions.UNESCAPE);
        this.print              = ScriptFunction.createBuiltin("print",      env._print_no_newline ? PRINT : PRINTLN);
        this.load               = ScriptFunction.createBuiltin("load",       LOAD);
        this.loadWithNewGlobal  = ScriptFunction.createBuiltin("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
        this.exit               = ScriptFunction.createBuiltin("exit",       EXIT);
        this.quit               = ScriptFunction.createBuiltin("quit",       EXIT);

        // built-in constructors
        this.builtinArray     = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
        this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
        this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
        this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
        this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);

        // initialize String.prototype.length to 0
        // add String.prototype.length
        final ScriptObject stringPrototype = getStringPrototype();
        stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);

        // set isArray flag on Array.prototype
        final ScriptObject arrayPrototype = getArrayPrototype();
        arrayPrototype.setIsArray();

        // Error stuff
        initErrorObjects();

        // java access
        if (! env._no_java) {
            this.javaApi = LAZY_SENTINEL;
            this.javaImporter = LAZY_SENTINEL;
            initJavaAccess();
        }

        if (! env._no_typed_arrays) {
            this.arrayBuffer       = LAZY_SENTINEL;
            this.dataView          = LAZY_SENTINEL;
            this.int8Array         = LAZY_SENTINEL;
            this.uint8Array        = LAZY_SENTINEL;
            this.uint8ClampedArray = LAZY_SENTINEL;
            this.int16Array        = LAZY_SENTINEL;
            this.uint16Array       = LAZY_SENTINEL;
            this.int32Array        = LAZY_SENTINEL;
            this.uint32Array       = LAZY_SENTINEL;
            this.float32Array      = LAZY_SENTINEL;
            this.float64Array      = LAZY_SENTINEL;
        }

        if (env._scripting) {
            initScripting(env);
        }

        if (Context.DEBUG) {
            boolean debugOkay;
            final SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                try {
                    sm.checkPermission(new RuntimePermission(Context.NASHORN_DEBUG_MODE));
                    debugOkay = true;
                } catch (final SecurityException ignored) {
                    // if no permission, don't initialize Debug object
                    debugOkay = false;
                }

            } else {
                debugOkay = true;
            }

            if (debugOkay) {
                initDebug();
            }
        }

        copyBuiltins();

        // expose script (command line) arguments as "arguments" property of global
        arguments = wrapAsObject(env.getArguments().toArray());
        if (env._scripting) {
            // synonym for "arguments" in scripting mode
            addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, arguments);
        }

        if (eng != null) {
            // default file name
            addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
            // __noSuchProperty__ hook for ScriptContext search of missing variables
            final ScriptFunction noSuchProp = ScriptFunction.createStrictBuiltin(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
            addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
        }
    }

    private void initErrorObjects() {
        // Error objects
        this.builtinError = initConstructor("Error", ScriptFunction.class);
        final ScriptObject errorProto = getErrorPrototype();

        // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
        final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", NativeError.GET_STACK);
        final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", NativeError.SET_STACK);
        errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
        final ScriptFunction getLineNumber = ScriptFunction.createBuiltin("getLineNumber", NativeError.GET_LINENUMBER);
        final ScriptFunction setLineNumber = ScriptFunction.createBuiltin("setLineNumber", NativeError.SET_LINENUMBER);
        errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
        final ScriptFunction getColumnNumber = ScriptFunction.createBuiltin("getColumnNumber", NativeError.GET_COLUMNNUMBER);
        final ScriptFunction setColumnNumber = ScriptFunction.createBuiltin("setColumnNumber", NativeError.SET_COLUMNNUMBER);
        errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
        final ScriptFunction getFileName = ScriptFunction.createBuiltin("getFileName", NativeError.GET_FILENAME);
        final ScriptFunction setFileName = ScriptFunction.createBuiltin("setFileName", NativeError.SET_FILENAME);
        errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);

        // ECMA 15.11.4.2 Error.prototype.name
        // Error.prototype.name = "Error";
        errorProto.set(NativeError.NAME, "Error", 0);
        // ECMA 15.11.4.3 Error.prototype.message
        // Error.prototype.message = "";
        errorProto.set(NativeError.MESSAGE, "", 0);

        tagBuiltinProperties("Error", builtinError);

        this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
        this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
        this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
    }

    private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
        final ScriptFunction cons = initConstructor(name, ScriptFunction.class);
        final ScriptObject prototype = ScriptFunction.getPrototype(cons);
        prototype.set(NativeError.NAME, name, 0);
        prototype.set(NativeError.MESSAGE, "", 0);
        prototype.setInitialProto(errorProto);
        tagBuiltinProperties(name, cons);
        return cons;
    }

    private void initJavaAccess() {
        final ScriptObject objectProto = getObjectPrototype();
        this.builtinPackages = new NativeJavaPackage("", objectProto);
        this.builtinCom = new NativeJavaPackage("com", objectProto);
        this.builtinEdu = new NativeJavaPackage("edu", objectProto);
        this.builtinJava = new NativeJavaPackage("java", objectProto);
        this.builtinJavafx = new NativeJavaPackage("javafx", objectProto);
        this.builtinJavax = new NativeJavaPackage("javax", objectProto);
        this.builtinOrg = new NativeJavaPackage("org", objectProto);
    }

    private void initScripting(final ScriptEnvironment scriptEnv) {
        ScriptObject value;
        value = ScriptFunction.createBuiltin("readLine", ScriptingFunctions.READLINE);
        addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);

        value = ScriptFunction.createBuiltin("readFully", ScriptingFunctions.READFULLY);
        addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);

        final String execName = ScriptingFunctions.EXEC_NAME;
        value = ScriptFunction.createBuiltin(execName, ScriptingFunctions.EXEC);
        value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false);

        addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);

        // Nashorn extension: global.echo (scripting-mode-only)
        // alias for "print"
        value = (ScriptObject)get("print");
        addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);

        // Nashorn extension: global.$OPTIONS (scripting-mode-only)
        final ScriptObject options = newObject();
        copyOptions(options, scriptEnv);
        addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);

        // Nashorn extension: global.$ENV (scripting-mode-only)
        if (System.getSecurityManager() == null) {
            // do not fill $ENV if we have a security manager around
            // Retrieve current state of ENV variables.
            final ScriptObject env = newObject();
            env.putAll(System.getenv(), scriptEnv._strict);

            // Some platforms, e.g., Windows, do not define the PWD environment
            // variable, so that the $ENV.PWD property needs to be explicitly
            // set.
            if (!env.containsKey(ScriptingFunctions.PWD_NAME)) {
                env.put(ScriptingFunctions.PWD_NAME, System.getProperty("user.dir"), scriptEnv._strict);
            }

            addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
        } else {
            addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
        }

        // add other special properties for exec support
        addOwnProperty(ScriptingFunctions.OUT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
        addOwnProperty(ScriptingFunctions.ERR_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
        addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
    }

    private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
        for (final Field f : scriptEnv.getClass().getFields()) {
            try {
                options.set(f.getName(), f.get(scriptEnv), 0);
            } catch (final IllegalArgumentException | IllegalAccessException exp) {
                throw new RuntimeException(exp);
            }
        }
    }

    private void copyBuiltins() {
        this.array             = this.builtinArray;
        this._boolean          = this.builtinBoolean;
        this.error             = this.builtinError;
        this.function          = this.builtinFunction;
        this.com               = this.builtinCom;
        this.edu               = this.builtinEdu;
        this.java              = this.builtinJava;
        this.javafx            = this.builtinJavafx;
        this.javax             = this.builtinJavax;
        this.org               = this.builtinOrg;
        this.math              = this.builtinMath;
        this.number            = this.builtinNumber;
        this.object            = this.builtinObject;
        this.packages          = this.builtinPackages;
        this.referenceError    = this.builtinReferenceError;
        this.string            = this.builtinString;
        this.syntaxError       = this.builtinSyntaxError;
        this.typeError         = this.builtinTypeError;
    }

    private void initDebug() {
        this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug", ScriptObject.class));
    }

    private Object printImpl(final boolean newLine, final Object... objects) {
        final ScriptContext sc = currentContext();
        @SuppressWarnings("resource")
        final PrintWriter out = sc != null? new PrintWriter(sc.getWriter()) : getContext().getEnv().getOut();
        final StringBuilder sb = new StringBuilder();

        for (final Object obj : objects) {
            if (sb.length() != 0) {
                sb.append(' ');
            }

            sb.append(JSType.toString(obj));
        }

        // Print all at once to ensure thread friendly result.
        if (newLine) {
            out.println(sb.toString());
        } else {
            out.print(sb.toString());
        }

        out.flush();

        return UNDEFINED;
    }

    private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
        try {
            // Assuming class name pattern for built-in JS constructors.
            final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");

            sb.append("Native");
            sb.append(name);
            sb.append("$Constructor");

            final Class<?> funcClass = Class.forName(sb.toString());
            final T res = clazz.cast(funcClass.newInstance());

            if (res instanceof ScriptFunction) {
                // All global constructor prototypes are not-writable,
                // not-enumerable and not-configurable.
                final ScriptFunction func = (ScriptFunction)res;
                func.modifyOwnProperty(func.getProperty("prototype"), Attribute.NON_ENUMERABLE_CONSTANT);
            }

            if (res.getProto() == null) {
                res.setInitialProto(getObjectPrototype());
            }

            res.setIsBuiltin();

            return res;
        } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private List<jdk.nashorn.internal.runtime.Property> extractBuiltinProperties(final String name, final ScriptObject func) {
        final List<jdk.nashorn.internal.runtime.Property> list = new ArrayList<>();

        list.addAll(Arrays.asList(func.getMap().getProperties()));

        if (func instanceof ScriptFunction) {
            final ScriptObject proto = ScriptFunction.getPrototype((ScriptFunction)func);
            if (proto != null) {
                list.addAll(Arrays.asList(proto.getMap().getProperties()));
            }
        }

        final jdk.nashorn.internal.runtime.Property prop = getProperty(name);
        if (prop != null) {
            list.add(prop);
        }

        return list;
    }

    /**
     * Given a builtin object, traverse its properties recursively and associate them with a name that
     * will be a key to their invalidation switchpoint.
     * @param name name for key
     * @param func builtin script object
     */
    private void tagBuiltinProperties(final String name, final ScriptObject func) {
        SwitchPoint sp = context.getBuiltinSwitchPoint(name);
        if (sp == null) {
            sp = context.newBuiltinSwitchPoint(name);
        }

        //get all builtin properties in this builtin object and register switchpoints keyed on the propery name,
        //one overwrite destroys all for now, e.g. Function.prototype.apply = 17; also destroys Function.prototype.call etc
        for (final jdk.nashorn.internal.runtime.Property prop : extractBuiltinProperties(name, func)) {
            prop.setBuiltinSwitchPoint(sp);
        }
    }

    // Function and Object constructors are inter-dependent. Also,
    // Function.prototype
    // functions are not properly initialized. We fix the references here.
    // NOTE: be careful if you want to re-order the operations here. You may
    // have
    // to play with object references carefully!!
    private void initFunctionAndObject() {
        // First-n-foremost is Function

        this.builtinFunction = initConstructor("Function", ScriptFunction.class);

        // create global anonymous function
        final ScriptFunction anon = ScriptFunction.createAnonymous();
        // need to copy over members of Function.prototype to anon function
        anon.addBoundProperties(getFunctionPrototype());

        // Function.prototype === Object.getPrototypeOf(Function) ===
        // <anon-function>
        builtinFunction.setInitialProto(anon);
        builtinFunction.setPrototype(anon);
        anon.set("constructor", builtinFunction, 0);
        anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));

        // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
        this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER);
        typeErrorThrower.preventExtensions();

        // now initialize Object
        this.builtinObject = initConstructor("Object", ScriptFunction.class);
        final ScriptObject ObjectPrototype = getObjectPrototype();
        // Object.getPrototypeOf(Function.prototype) === Object.prototype
        anon.setInitialProto(ObjectPrototype);

        // ES6 draft compliant __proto__ property of Object.prototype
        // accessors on Object.prototype for "__proto__"
        final ScriptFunction getProto = ScriptFunction.createBuiltin("getProto", NativeObject.GET__PROTO__);
        final ScriptFunction setProto = ScriptFunction.createBuiltin("setProto", NativeObject.SET__PROTO__);
        ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);

        // Function valued properties of Function.prototype were not properly
        // initialized. Because, these were created before global.function and
        // global.object were not initialized.
        jdk.nashorn.internal.runtime.Property[] properties = getFunctionPrototype().getMap().getProperties();
        for (final jdk.nashorn.internal.runtime.Property property : properties) {
            final Object key = property.getKey();
            final Object value = builtinFunction.get(key);

            if (value instanceof ScriptFunction && value != anon) {
                final ScriptFunction func = (ScriptFunction)value;
                func.setInitialProto(getFunctionPrototype());
                final ScriptObject prototype = ScriptFunction.getPrototype(func);
                if (prototype != null) {
                    prototype.setInitialProto(ObjectPrototype);
                }
            }
        }

        // For function valued properties of Object and Object.prototype, make
        // sure prototype's proto chain ends with Object.prototype
        for (final jdk.nashorn.internal.runtime.Property property : builtinObject.getMap().getProperties()) {
            final Object key = property.getKey();
            final Object value = builtinObject.get(key);

            if (value instanceof ScriptFunction) {
                final ScriptFunction func = (ScriptFunction)value;
                final ScriptObject prototype = ScriptFunction.getPrototype(func);
                if (prototype != null) {
                    prototype.setInitialProto(ObjectPrototype);
                }
            }
        }

        properties = getObjectPrototype().getMap().getProperties();

        for (final jdk.nashorn.internal.runtime.Property property : properties) {
            final Object key   = property.getKey();
            if (key.equals("constructor")) {
                continue;
            }

            final Object value = ObjectPrototype.get(key);
            if (value instanceof ScriptFunction) {
                final ScriptFunction func = (ScriptFunction)value;
                final ScriptObject prototype = ScriptFunction.getPrototype(func);
                if (prototype != null) {
                    prototype.setInitialProto(ObjectPrototype);
                }
            }
        }

        tagBuiltinProperties("Object", builtinObject);
        tagBuiltinProperties("Function", builtinFunction);
        tagBuiltinProperties("Function", anon);
    }

    private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
        return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
    }

    RegExpResult getLastRegExpResult() {
        return lastRegExpResult;
    }

    void setLastRegExpResult(final RegExpResult regExpResult) {
        this.lastRegExpResult = regExpResult;
    }

    @Override
    protected boolean isGlobal() {
        return true;
    }

    /**
     * A class representing the ES6 global lexical scope.
     */
    private static class LexicalScope extends ScriptObject {

        LexicalScope(final Global global) {
            super(global, PropertyMap.newMap());
        }

        @Override
        protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
            return filterInvocation(super.findGetMethod(desc, request, operator));
        }

        @Override
        protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
            return filterInvocation(super.findSetMethod(desc, request));
        }

        @Override
        protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property, final boolean extensible) {
            // We override this method just to make it callable by Global
            return super.addBoundProperty(propMap, source, property, extensible);
        }

        private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
            final MethodType type = invocation.getInvocation().type();
            return invocation.asType(type.changeParameterType(0, Object.class)).filterArguments(0, LEXICAL_SCOPE_FILTER);
        }
    }

}
