/*
 * 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.typeError;
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.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.GlobalFunctions;
import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.NativeJavaPackage;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.PropertyDescriptor;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.regexp.RegExpResult;
import jdk.nashorn.internal.runtime.Scope;
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.Source;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
import jdk.nashorn.internal.scripts.JO;

/**
 * Representation of global scope.
 */
@ScriptClass("Global")
public final class Global extends ScriptObject implements GlobalObject, Scope {
    private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
    private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);

    /** 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 final Object NaN = Double.NaN;

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

    /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
    public 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;

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

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

    /** ECMA 15.12 - The JSON object */
    @Property(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object json;

    /** Nashorn extension: global.JSAdapter */
    @Property(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object jsadapter;

    /** 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;

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

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

    /** 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;

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

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

    /** TypedArray (int8) */
    @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object int8Array;

    /** TypedArray (uint8) */
    @Property(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object uint8Array;

    /** TypedArray (uint8) - Clamped */
    @Property(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object uint8ClampedArray;

    /** TypedArray (int16) */
    @Property(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object int16Array;

    /** TypedArray (uint16) */
    @Property(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object uint16Array;

    /** TypedArray (int32) */
    @Property(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object int32Array;

    /** TypedArray (uint32) */
    @Property(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object uint32Array;

    /** TypedArray (float32) */
    @Property(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object float32Array;

    /** TypedArray (float64) */
    @Property(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
    public 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;

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

    /** Nashorn extension: global.Java Object constructor. */
    @Property(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
    public volatile Object javaApi;

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

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

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

    /** Used as Date.prototype's default value */
    public NativeDate   DEFAULT_DATE;

    /** Used as RegExp.prototype's default value */
    public NativeRegExp 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 ScriptObject   builtinJavaImporter;
    private ScriptObject   builtinJavaApi;
    private ScriptObject   builtinArrayBuffer;
    private ScriptObject   builtinInt8Array;
    private ScriptObject   builtinUint8Array;
    private ScriptObject   builtinUint8ClampedArray;
    private ScriptObject   builtinInt16Array;
    private ScriptObject   builtinUint16Array;
    private ScriptObject   builtinInt32Array;
    private ScriptObject   builtinUint32Array;
    private ScriptObject   builtinFloat32Array;
    private ScriptObject   builtinFloat64Array;

    private PropertyMap    accessorPropertyDescriptorMap;
    private PropertyMap    arrayBufferViewMap;
    private PropertyMap    dataPropertyDescriptorMap;
    private PropertyMap    genericPropertyDescriptorMap;
    private PropertyMap    nativeArgumentsMap;
    private PropertyMap    nativeArrayMap;
    private PropertyMap    nativeArrayBufferMap;
    private PropertyMap    nativeBooleanMap;
    private PropertyMap    nativeDateMap;
    private PropertyMap    nativeErrorMap;
    private PropertyMap    nativeEvalErrorMap;
    private PropertyMap    nativeJSAdapterMap;
    private PropertyMap    nativeJavaImporterMap;
    private PropertyMap    nativeNumberMap;
    private PropertyMap    nativeRangeErrorMap;
    private PropertyMap    nativeReferenceErrorMap;
    private PropertyMap    nativeRegExpMap;
    private PropertyMap    nativeRegExpExecResultMap;
    private PropertyMap    nativeStrictArgumentsMap;
    private PropertyMap    nativeStringMap;
    private PropertyMap    nativeSyntaxErrorMap;
    private PropertyMap    nativeTypeErrorMap;
    private PropertyMap    nativeURIErrorMap;
    private PropertyMap    prototypeObjectMap;
    private PropertyMap    objectMap;
    private PropertyMap    functionMap;
    private PropertyMap    anonymousFunctionMap;
    private PropertyMap    strictFunctionMap;
    private PropertyMap    boundFunctionMap;

    // Flag to indicate that a split method issued a return statement
    private int splitState = -1;

    // class cache
    private ClassCache classCache;

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

    private static final MethodHandle EVAL              = findOwnMH("eval",              Object.class, Object.class, Object.class);
    private static final MethodHandle PRINT             = findOwnMH("print",             Object.class, Object.class, Object[].class);
    private static final MethodHandle PRINTLN           = findOwnMH("println",           Object.class, Object.class, Object[].class);
    private static final MethodHandle LOAD              = findOwnMH("load",              Object.class, Object.class, Object.class);
    private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object[].class);
    private static final MethodHandle EXIT              = findOwnMH("exit",              Object.class, Object.class, Object.class);

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

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

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

    // 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));
        }

        // null check on context
        context.getClass();

        /*
         * Duplicate global's map and use it. This way the initial Map filled
         * by nasgen (referenced from static field in this class) is retained
         * 'as is' (as that one is process wide singleton.
         */
        return $nasgenmap$.duplicate();
    }

    /**
     * Constructor
     *
     * @param context the context
     */
    public Global(final Context context) {
        super(checkAndGetMap(context));
        this.context = context;
        this.setIsScope();

        final int cacheSize = context.getEnv()._class_cache_size;
        if (cacheSize > 0) {
            classCache = new ClassCache(cacheSize);
        }
    }

    /**
     * Script access to "current" Global instance
     *
     * @return the global singleton
     */
    public static Global instance() {
        ScriptObject global = Context.getGlobal();
        if (! (global instanceof Global)) {
            throw new IllegalStateException("no current global instance");
        }
        return (Global)global;
    }

    /**
     * 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();
    }

    // GlobalObject interface implementation

    @Override
    public boolean isOfContext(final Context ctxt) {
        return this.context == ctxt;
    }

    @Override
    public boolean isStrictContext() {
        return context.getEnv()._strict;
    }

    @Override
    public void initBuiltinObjects() {
        if (this.builtinObject != null) {
            // already initialized, just return
            return;
        }

        init();
    }

    @Override
    public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
        return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
    }

    @Override
    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 (obj instanceof String || obj instanceof ConsString) {
            return new NativeString((CharSequence)obj, this);
        } else if (obj instanceof Object[]) { // extension
            return new NativeArray((Object[])obj);
        } else if (obj instanceof double[]) { // extension
            return new NativeArray((double[])obj);
        } else if (obj instanceof long[]) {
            return new NativeArray((long[])obj);
        } else if (obj instanceof int[]) {
            return new NativeArray((int[])obj);
        } else {
            // FIXME: more special cases? Map? List?
            return obj;
        }
    }

    @Override
    public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
        if (self instanceof String || self instanceof ConsString) {
            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);
    }

    @Override
    public ScriptObject newObject() {
        return new JO(getObjectPrototype(), getObjectMap());
    }

    @Override
    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;
    }

    @Override
    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;
    }

    @Override
    public ScriptObject newError(final String msg) {
        return new NativeError(msg, this);
    }

    @Override
    public ScriptObject newEvalError(final String msg) {
        return new NativeEvalError(msg, this);
    }

    @Override
    public ScriptObject newRangeError(final String msg) {
        return new NativeRangeError(msg, this);
    }

    @Override
    public ScriptObject newReferenceError(final String msg) {
        return new NativeReferenceError(msg, this);
    }

    @Override
    public ScriptObject newSyntaxError(final String msg) {
        return new NativeSyntaxError(msg, this);
    }

    @Override
    public ScriptObject newTypeError(final String msg) {
        return new NativeTypeError(msg, this);
    }

    @Override
    public ScriptObject newURIError(final String msg) {
        return new NativeURIError(msg, this);
    }

    @Override
    public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
        return new GenericPropertyDescriptor(configurable, enumerable, this);
    }

    @Override
    public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
        return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
    }

    @Override
    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;
    }


    /**
     * Cache for compiled script classes.
     */
    @SuppressWarnings("serial")
    private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
        private final int size;
        private final ReferenceQueue<Class<?>> queue;

        ClassCache(int size) {
            super(size, 0.75f, true);
            this.size = size;
            this.queue = new ReferenceQueue<>();
        }

        void cache(final Source source, final Class<?> clazz) {
            put(source, new ClassReference(clazz, queue, source));
        }

        @Override
        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
            return size() > size;
        }

        @Override
        public ClassReference get(Object key) {
            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
                remove(ref.source);
            }
            return super.get(key);
        }

    }

    private static class ClassReference extends SoftReference<Class<?>> {
        private final Source source;

        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
            super(clazz, queue);
            this.source = source;
        }
    }

    // Class cache management
    @Override
    public Class<?> findCachedClass(final Source source) {
        assert classCache != null : "Class cache used without being initialized";
        ClassReference ref = classCache.get(source);
        return ref != null ? ref.get() : null;
    }

    @Override
    public void cacheClass(final Source source, final Class<?> clazz) {
        assert classCache != null : "Class cache used without being initialized";
        classCache.cache(source, clazz);
    }

    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<>();

    @Override
    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
        return getLazilyCreatedValue(key, creator, namedInvokers);
    }

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

    @Override
    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
        return getLazilyCreatedValue(key, creator, dynamicInvokers);
    }

    /**
     * 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, UNDEFINED, UNDEFINED, UNDEFINED);
    }

    /**
     * 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 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 Object strict) {
        if (!(str instanceof String || str instanceof ConsString)) {
            return str;
        }
        final Global global = Global.instance();
        final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;

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

    /**
     * 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 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 printImpl(true, objects);
    }

    /**
     * Global load implementation - Nashorn extension
     *
     * @param self    scope
     * @param source  source to load
     *
     * @return result of load (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.instance();
        final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
        return global.getContext().load(scope, source);
    }

    /**
     * Global loadWithNewGlobal implementation - Nashorn extension
     *
     * @param self scope
     * @param args from plus (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.instance();
        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
    ScriptObject getFunctionPrototype() {
        return ScriptFunction.getPrototype(builtinFunction);
    }

    ScriptObject getObjectPrototype() {
        return ScriptFunction.getPrototype(builtinObject);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Builtin PropertyMap accessors
    PropertyMap getAccessorPropertyDescriptorMap() {
        return accessorPropertyDescriptorMap;
    }

    PropertyMap getArrayBufferViewMap() {
        return arrayBufferViewMap;
    }

    PropertyMap getDataPropertyDescriptorMap() {
        return dataPropertyDescriptorMap;
    }

    PropertyMap getGenericPropertyDescriptorMap() {
        return genericPropertyDescriptorMap;
    }

    PropertyMap getArgumentsMap() {
        return nativeArgumentsMap;
    }

    PropertyMap getArrayMap() {
        return nativeArrayMap;
    }

    PropertyMap getArrayBufferMap() {
        return nativeArrayBufferMap;
    }

    PropertyMap getBooleanMap() {
        return nativeBooleanMap;
    }

    PropertyMap getDateMap() {
        return nativeDateMap;
    }

    PropertyMap getErrorMap() {
        return nativeErrorMap;
    }

    PropertyMap getEvalErrorMap() {
        return nativeEvalErrorMap;
    }

    PropertyMap getJSAdapterMap() {
        return nativeJSAdapterMap;
    }

    PropertyMap getJavaImporterMap() {
        return nativeJavaImporterMap;
    }

    PropertyMap getNumberMap() {
        return nativeNumberMap;
    }

    PropertyMap getRangeErrorMap() {
        return nativeRangeErrorMap;
    }

    PropertyMap getReferenceErrorMap() {
        return nativeReferenceErrorMap;
    }

    PropertyMap getRegExpMap() {
        return nativeRegExpMap;
    }

    PropertyMap getRegExpExecResultMap() {
        return nativeRegExpExecResultMap;
    }

    PropertyMap getStrictArgumentsMap() {
        return nativeStrictArgumentsMap;
    }

    PropertyMap getStringMap() {
        return nativeStringMap;
    }

    PropertyMap getSyntaxErrorMap() {
        return nativeSyntaxErrorMap;
    }

    PropertyMap getTypeErrorMap() {
        return nativeTypeErrorMap;
    }

    PropertyMap getURIErrorMap() {
        return nativeURIErrorMap;
    }

    PropertyMap getPrototypeObjectMap() {
        return prototypeObjectMap;
    }

    PropertyMap getObjectMap() {
        return objectMap;
    }

    PropertyMap getFunctionMap() {
        return functionMap;
    }

    PropertyMap getAnonymousFunctionMap() {
        return anonymousFunctionMap;
    }

    PropertyMap getStrictFunctionMap() {
        return strictFunctionMap;
    }

    PropertyMap getBoundFunctionMap() {
        return boundFunctionMap;
    }

    private ScriptFunction getBuiltinArray() {
        return builtinArray;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin array has not been overridden
     */
    public static boolean isBuiltinArray() {
        final Global instance = Global.instance();
        return instance.array == instance.getBuiltinArray();
    }

    private ScriptFunction getBuiltinBoolean() {
        return builtinBoolean;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin boolean has not been overridden
     */
    public static boolean isBuiltinBoolean() {
        final Global instance = Global.instance();
        return instance._boolean == instance.getBuiltinBoolean();
    }

    private ScriptFunction getBuiltinDate() {
        return builtinDate;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin date has not been overridden
     */
    public static boolean isBuiltinDate() {
        final Global instance = Global.instance();
        return instance.date == instance.getBuiltinDate();
    }

    private ScriptFunction getBuiltinError() {
        return builtinError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin error has not been overridden
     */
    public static boolean isBuiltinError() {
        final Global instance = Global.instance();
        return instance.error == instance.getBuiltinError();
    }

    private ScriptFunction getBuiltinEvalError() {
        return builtinEvalError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin eval error has not been overridden
     */
    public static boolean isBuiltinEvalError() {
        final Global instance = Global.instance();
        return instance.evalError == instance.getBuiltinEvalError();
    }

    private ScriptFunction getBuiltinFunction() {
        return builtinFunction;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin function has not been overridden
     */
    public static boolean isBuiltinFunction() {
        final Global instance = Global.instance();
        return instance.function == instance.getBuiltinFunction();
    }

    private ScriptFunction getBuiltinJSAdapter() {
        return builtinJSAdapter;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin JSAdapter has not been overridden
     */
    public static boolean isBuiltinJSAdapter() {
        final Global instance = Global.instance();
        return instance.jsadapter == instance.getBuiltinJSAdapter();
    }

    private ScriptObject getBuiltinJSON() {
        return builtinJSON;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin JSON has has not been overridden
     */
    public static boolean isBuiltinJSON() {
        final Global instance = Global.instance();
        return instance.json == instance.getBuiltinJSON();
    }

    private ScriptObject getBuiltinJava() {
        return builtinJava;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin Java has not been overridden
     */
    public static boolean isBuiltinJava() {
        final Global instance = Global.instance();
        return instance.java == instance.getBuiltinJava();
    }

    private ScriptObject getBuiltinJavax() {
        return builtinJavax;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin Javax has not been overridden
     */
    public static boolean isBuiltinJavax() {
        final Global instance = Global.instance();
        return instance.javax == instance.getBuiltinJavax();
    }

    private ScriptObject getBuiltinJavaImporter() {
        return builtinJavaImporter;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin Java importer has not been overridden
     */
    public static boolean isBuiltinJavaImporter() {
        final Global instance = Global.instance();
        return instance.javaImporter == instance.getBuiltinJavaImporter();
    }

    private ScriptObject getBuiltinMath() {
        return builtinMath;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin math has not been overridden
     */
    public static boolean isBuiltinMath() {
        final Global instance = Global.instance();
        return instance.math == instance.getBuiltinMath();
    }

    private ScriptFunction getBuiltinNumber() {
        return builtinNumber;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin number has not been overridden
     */
    public static boolean isBuiltinNumber() {
        final Global instance = Global.instance();
        return instance.number == instance.getBuiltinNumber();
    }

    private ScriptFunction getBuiltinObject() {
        return builtinObject;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin object has not been overridden
     */
    public static boolean isBuiltinObject() {
        final Global instance = Global.instance();
        return instance.object == instance.getBuiltinObject();
    }

    private ScriptObject getBuiltinPackages() {
        return builtinPackages;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin package has not been overridden
     */
    public static boolean isBuiltinPackages() {
        final Global instance = Global.instance();
        return instance.packages == instance.getBuiltinPackages();
    }

    private ScriptFunction getBuiltinRangeError() {
        return builtinRangeError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin range error has not been overridden
     */
    public static boolean isBuiltinRangeError() {
        final Global instance = Global.instance();
        return instance.rangeError == instance.getBuiltinRangeError();
    }

    private ScriptFunction getBuiltinReferenceError() {
        return builtinReferenceError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin reference error has not been overridden
     */
    public static boolean isBuiltinReferenceError() {
        final Global instance = Global.instance();
        return instance.referenceError == instance.getBuiltinReferenceError();
    }

    private ScriptFunction getBuiltinRegExp() {
        return builtinRegExp;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin regexp has not been overridden
     */
    public static boolean isBuiltinRegExp() {
        final Global instance = Global.instance();
        return instance.regexp == instance.getBuiltinRegExp();
    }

    private ScriptFunction getBuiltinString() {
        return builtinString;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin Java has not been overridden
     */
    public static boolean isBuiltinString() {
        final Global instance = Global.instance();
        return instance.string == instance.getBuiltinString();
    }

    private ScriptFunction getBuiltinSyntaxError() {
        return builtinSyntaxError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin syntax error has not been overridden
     */
    public static boolean isBuiltinSyntaxError() {
        final Global instance = Global.instance();
        return instance.syntaxError == instance.getBuiltinSyntaxError();
    }

    private ScriptFunction getBuiltinTypeError() {
        return builtinTypeError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin type error has not been overridden
     */
    public static boolean isBuiltinTypeError() {
        final Global instance = Global.instance();
        return instance.typeError == instance.getBuiltinTypeError();
    }

    private ScriptFunction getBuiltinURIError() {
        return builtinURIError;
    }

    /**
     * Called from compiled script code to test if builtin has been overridden
     *
     * @return true if builtin URI error has not been overridden
     */
    public static boolean isBuiltinURIError() {
        final Global instance = Global.instance();
        return instance.uriError == instance.getBuiltinURIError();
    }

    @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 long array.
     *
     * @param initial number values.
     * @return the new array
     */
    public static NativeArray allocate(final long[] 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;
    }

    /**
     * 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
     */
    public static void checkObject(final Object obj) {
        if (!(obj instanceof ScriptObject)) {
            throw typeError("not.an.object", ScriptRuntime.safeToString(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));
        }
    }

    /**
     * Get the current split state.
     *
     * @return current split state
     */
    @Override
    public int getSplitState() {
        return splitState;
    }

    /**
     * Set the current split state.
     *
     * @param state current split state
     */
    @Override
    public void setSplitState(final int state) {
        splitState = state;
    }

    private void init() {
        assert Context.getGlobal() == this : "this global is not set as current";

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

        // duplicate PropertyMaps of Native* classes
        copyInitialMaps(env);

        // initialize Function and Object constructor
        initFunctionAndObject();

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

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

        this.parseInt           = ScriptFunctionImpl.makeFunction("parseInt",   GlobalFunctions.PARSEINT);
        this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
        this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
        this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
        this.encodeURI          = ScriptFunctionImpl.makeFunction("encodeURI",  GlobalFunctions.ENCODE_URI);
        this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
        this.decodeURI          = ScriptFunctionImpl.makeFunction("decodeURI",  GlobalFunctions.DECODE_URI);
        this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
        this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
        this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
        this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
        this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
        this.loadWithNewGlobal  = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
        this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
        this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);

        // built-in constructors
        this.builtinArray     = (ScriptFunction)initConstructor("Array");
        this.builtinBoolean   = (ScriptFunction)initConstructor("Boolean");
        this.builtinDate      = (ScriptFunction)initConstructor("Date");
        this.builtinJSON      = initConstructor("JSON");
        this.builtinJSAdapter = (ScriptFunction)initConstructor("JSAdapter");
        this.builtinMath      = initConstructor("Math");
        this.builtinNumber    = (ScriptFunction)initConstructor("Number");
        this.builtinRegExp    = (ScriptFunction)initConstructor("RegExp");
        this.builtinString    = (ScriptFunction)initConstructor("String");

        // 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();

        this.DEFAULT_DATE = new NativeDate(Double.NaN, this);

        // initialize default regexp object
        this.DEFAULT_REGEXP = new NativeRegExp("(?:)", this);

        // RegExp.prototype should behave like a RegExp object. So copy the
        // properties.
        final ScriptObject regExpProto = getRegExpPrototype();
        regExpProto.addBoundProperties(DEFAULT_REGEXP);

        // Error stuff
        initErrorObjects();

        // java access
        if (! env._no_java) {
            initJavaAccess();
        }

        if (! env._no_typed_arrays) {
            initTypedArray();
        }

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

        if (Context.DEBUG && System.getSecurityManager() == null) {
            initDebug();
        }

        copyBuiltins();

        // initialized with strings so that typeof will work as expected.
        this.__FILE__ = "";
        this.__DIR__  = "";
        this.__LINE__ = 0.0;

        // expose script (command line) arguments as "arguments" property of global
        final List<String> arguments = env.getArguments();
        final Object argsObj = wrapAsObject(arguments.toArray());

        addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
        if (env._scripting) {
            // synonym for "arguments" in scripting mode
            addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
        }
    }

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

        // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
        final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
        final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
        errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
        final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
        final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
        errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
        final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
        final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
        errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
        final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
        final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("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", false);
        // ECMA 15.11.4.3 Error.prototype.message
        // Error.prototype.message = "";
        errorProto.set(NativeError.MESSAGE, "", false);

        this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
        this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
        this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
        this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
        this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
        this.builtinURIError = initErrorSubtype("URIError", errorProto);
    }

    private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
        final ScriptObject cons = initConstructor(name);
        final ScriptObject prototype = ScriptFunction.getPrototype(cons);
        prototype.set(NativeError.NAME, name, false);
        prototype.set(NativeError.MESSAGE, "", false);
        prototype.setProto(errorProto);
        return (ScriptFunction)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);
        this.builtinJavaImporter = initConstructor("JavaImporter");
        this.builtinJavaApi = initConstructor("Java");
    }

    private void initScripting(final ScriptEnvironment scriptEnv) {
        Object value;
        value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
        addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);

        value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
        addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);

        final String execName = ScriptingFunctions.EXEC_NAME;
        value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
        addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);

        // Nashorn extension: global.echo (scripting-mode-only)
        // alias for "print"
        value = 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);
            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 (Field f : scriptEnv.getClass().getFields()) {
            try {
                options.set(f.getName(), f.get(scriptEnv), false);
            } catch (final IllegalArgumentException | IllegalAccessException exp) {
                throw new RuntimeException(exp);
            }
        }
    }

    private void initTypedArray() {
        this.builtinArrayBuffer       = initConstructor("ArrayBuffer");
        this.builtinInt8Array         = initConstructor("Int8Array");
        this.builtinUint8Array        = initConstructor("Uint8Array");
        this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
        this.builtinInt16Array        = initConstructor("Int16Array");
        this.builtinUint16Array       = initConstructor("Uint16Array");
        this.builtinInt32Array        = initConstructor("Int32Array");
        this.builtinUint32Array       = initConstructor("Uint32Array");
        this.builtinFloat32Array      = initConstructor("Float32Array");
        this.builtinFloat64Array      = initConstructor("Float64Array");
    }

    private void copyBuiltins() {
        this.array             = this.builtinArray;
        this._boolean          = this.builtinBoolean;
        this.date              = this.builtinDate;
        this.error             = this.builtinError;
        this.evalError         = this.builtinEvalError;
        this.function          = this.builtinFunction;
        this.jsadapter         = this.builtinJSAdapter;
        this.json              = this.builtinJSON;
        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.javaImporter      = this.builtinJavaImporter;
        this.javaApi           = this.builtinJavaApi;
        this.math              = this.builtinMath;
        this.number            = this.builtinNumber;
        this.object            = this.builtinObject;
        this.packages          = this.builtinPackages;
        this.rangeError        = this.builtinRangeError;
        this.referenceError    = this.builtinReferenceError;
        this.regexp            = this.builtinRegExp;
        this.string            = this.builtinString;
        this.syntaxError       = this.builtinSyntaxError;
        this.typeError         = this.builtinTypeError;
        this.uriError          = this.builtinURIError;
        this.arrayBuffer       = this.builtinArrayBuffer;
        this.int8Array         = this.builtinInt8Array;
        this.uint8Array        = this.builtinUint8Array;
        this.uint8ClampedArray = this.builtinUint8ClampedArray;
        this.int16Array        = this.builtinInt16Array;
        this.uint16Array       = this.builtinUint16Array;
        this.int32Array        = this.builtinInt32Array;
        this.uint32Array       = this.builtinUint32Array;
        this.float32Array      = this.builtinFloat32Array;
        this.float64Array      = this.builtinFloat64Array;
    }

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

    @SuppressWarnings("resource")
    private static Object printImpl(final boolean newLine, final Object... objects) {
        final PrintWriter out = Global.getEnv().getOut();
        final StringBuilder sb = new StringBuilder();

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

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

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

        out.flush();

        return UNDEFINED;
    }

    /**
     * These classes are generated by nasgen tool and so we have to use
     * reflection to load and create new instance of these classes.
     */
    private ScriptObject initConstructor(final String name) {
        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 ScriptObject res       = (ScriptObject)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.setProto(getObjectPrototype());
            }

            return res;

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

    private void copyInitialMaps(final ScriptEnvironment env) {
        this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
        this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
        this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
        this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
        this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
        this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
        this.nativeDateMap = NativeDate.getInitialMap().duplicate();
        this.nativeErrorMap = NativeError.getInitialMap().duplicate();
        this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
        this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
        this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
        this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
        this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
        this.nativeRegExpMap = NativeRegExp.getInitialMap().duplicate();
        this.nativeRegExpExecResultMap = NativeRegExpExecResult.getInitialMap().duplicate();
        this.nativeStrictArgumentsMap = NativeStrictArguments.getInitialMap().duplicate();
        this.nativeStringMap = NativeString.getInitialMap().duplicate();
        this.nativeSyntaxErrorMap = NativeSyntaxError.getInitialMap().duplicate();
        this.nativeTypeErrorMap = NativeTypeError.getInitialMap().duplicate();
        this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
        this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
        this.objectMap = JO.getInitialMap().duplicate();
        this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate();
        this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
        this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
        this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();

        // java
        if (! env._no_java) {
            this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
        }

        // typed arrays
        if (! env._no_typed_arrays) {
            this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
            this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
        }
    }

    // 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 = (ScriptFunction)initConstructor("Function");

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

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

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

        // 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.setProto(getFunctionPrototype());
                final ScriptObject prototype = ScriptFunction.getPrototype(func);
                if (prototype != null) {
                    prototype.setProto(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.setProto(ObjectPrototype);
                }
            }
        }

        properties = getObjectPrototype().getMap().getProperties();
        for (final jdk.nashorn.internal.runtime.Property property : properties) {
            final Object key   = property.getKey();
            final Object value = ObjectPrototype.get(key);

            if (key.equals("constructor")) {
                continue;
            }

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

    private static MethodHandle findOwnMH(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;
    }

}
