<commit_before>/**
 * Copyright (c) 2012-2013 <NAME>
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */
package com.github.anba.es6draft.runtime;

import static com.github.anba.es6draft.runtime.AbstractOperations.Get;
import static com.github.anba.es6draft.runtime.ExecutionContext.newScriptExecutionContext;

import java.text.Collator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;

import com.github.anba.es6draft.runtime.internal.CompatibilityOption;
import com.github.anba.es6draft.runtime.internal.Messages;
import com.github.anba.es6draft.runtime.internal.ObjectAllocator;
import com.github.anba.es6draft.runtime.modules.Loader;
import com.github.anba.es6draft.runtime.objects.*;
import com.github.anba.es6draft.runtime.objects.NativeErrorConstructor.ErrorType;
import com.github.anba.es6draft.runtime.objects.binary.ArrayBufferConstructor;
import com.github.anba.es6draft.runtime.objects.binary.ArrayBufferPrototype;
import com.github.anba.es6draft.runtime.objects.binary.DataViewConstructor;
import com.github.anba.es6draft.runtime.objects.binary.DataViewPrototype;
import com.github.anba.es6draft.runtime.objects.binary.ElementType;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayConstructor;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayConstructorPrototype;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayPrototype;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayPrototypePrototype;
import com.github.anba.es6draft.runtime.objects.internal.ListIteratorPrototype;
import com.github.anba.es6draft.runtime.objects.intl.CollatorConstructor;
import com.github.anba.es6draft.runtime.objects.intl.CollatorPrototype;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatConstructor;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatPrototype;
import com.github.anba.es6draft.runtime.objects.intl.IntlObject;
import com.github.anba.es6draft.runtime.objects.intl.NumberFormatConstructor;
import com.github.anba.es6draft.runtime.objects.intl.NumberFormatPrototype;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorFunctionConstructor;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorFunctionPrototype;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorPrototype;
import com.github.anba.es6draft.runtime.objects.reflect.Reflect;
import com.github.anba.es6draft.runtime.types.Callable;
import com.github.anba.es6draft.runtime.types.Intrinsics;
import com.github.anba.es6draft.runtime.types.ScriptObject;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryFunction;

/**
 * <h1>10 Executable Code and Execution Contexts</h1>
 * <ul>
 * <li>10.3 Code Realms
 * </ul>
 */
public class Realm {
    /**
     * [[intrinsics]]
     */
    private Map<Intrinsics, ScriptObject> intrinsics = new EnumMap<>(Intrinsics.class);

    /**
     * [[globalThis]]
     */
    private GlobalObject globalThis;

    /**
     * [[globalEnv]]
     */
    private LexicalEnvironment globalEnv;

    /**
     * [[loader]]
     */
    private Loader loader;

    /**
     * [[ThrowTypeError]]
     */
    private Callable throwTypeError;

    private Callable builtinEval;

    private ExecutionContext defaultContext;

    private Set<CompatibilityOption> options;

    private Locale locale = Locale.getDefault();
    private TimeZone timezone = TimeZone.getDefault();
    private Messages messages = Messages.create(locale);

    // TODO: move into function source object
    private Map<String, ScriptObject> templateCallSites = new HashMap<>();

    private Realm() {
    }

    /**
     * [[intrinsics]]
     */
    public ScriptObject getIntrinsic(Intrinsics id) {
        return intrinsics.get(id);
    }

    /**
     * [[globalThis]]
     */
    public GlobalObject getGlobalThis() {
        return globalThis;
    }

    /**
     * [[globalEnv]]
     */
    public LexicalEnvironment getGlobalEnv() {
        return globalEnv;
    }

    /**
     * [[loader]]
     */
    public Loader getLoader() {
        return loader;
    }

    /**
     * [[ThrowTypeError]]
     */
    public Callable getThrowTypeError() {
        assert throwTypeError != null : "throwTypeError not yet initialised";
        return throwTypeError;
    }

    /**
     * Returns the default execution context for this realm
     */
    public ExecutionContext defaultContext() {
        return defaultContext;
    }

    private AtomicInteger evalCounter = new AtomicInteger(0);
    private AtomicInteger functionCounter = new AtomicInteger(0);

    /**
     * Next class name for eval scripts
     * 
     * @see Eval
     */
    public String nextEvalName() {
        return "Eval_" + evalCounter.incrementAndGet();
    }

    /**
     * Next class name for functions
     * 
     * @see FunctionConstructor
     * @see GeneratorFunctionConstructor
     */
    public String nextFunctionName() {
        return "Function_" + functionCounter.incrementAndGet();
    }

    /**
     * Returns this realm's locale
     */
    public Locale getLocale() {
        return locale;
    }

    /**
     * Returns this realm's timezone
     */
    public TimeZone getTimezone() {
        return timezone;
    }

    /**
     * Returns the localised message for {@code key}
     */
    public String message(Messages.Key key) {
        return messages.getString(key);
    }

    /**
     * Returns a reference to the built-in <code>eval</code> function
     */
    public Callable getBuiltinEval() {
        return builtinEval;
    }

    /**
     * Returns the compatibility options for this realm instance
     */
    public Set<CompatibilityOption> getOptions() {
        return options;
    }

    public boolean isEnabled(CompatibilityOption option) {
        return options.contains(option);
    }

    /**
     * Returns the template call-site object for {@code key}
     */
    public ScriptObject getTemplateCallSite(String key) {
        return templateCallSites.get(key);
    }

    /**
     * Stores the template call-site object
     */
    public void addTemplateCallSite(String key, ScriptObject callSite) {
        templateCallSites.put(key, callSite);
    }

    /**
     * Returns a {@link Collator} for this realm's locale
     * 
     * @deprecated No longer used
     */
    @Deprecated
    public Collator getCollator() {
        Collator collator = Collator.getInstance(locale);
        // Use Normalised Form D for comparison (cf. 15.5.4.9, Note 2)
        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
        // `"\u0001".localeCompare("\u0002") == -1` should yield true
        collator.setStrength(Collator.IDENTICAL);
        return collator;
    }

    private static final ObjectAllocator<GlobalObject> DEFAULT_GLOBAL_OBJECT = new ObjectAllocator<GlobalObject>() {
        @Override
        public GlobalObject newInstance(Realm realm) {
            return new GlobalObject(realm);
        }
    };

    public static Realm newRealm() {
        return newRealm(DEFAULT_GLOBAL_OBJECT, CompatibilityOption.WebCompatibility());
    }

    public static Realm newRealm(ObjectAllocator<? extends GlobalObject> allocator,
            Set<CompatibilityOption> options) {
        Realm realm = new Realm();
        GlobalObject globalThis = allocator.newInstance(realm);
        ExecutionContext defaultContext = newScriptExecutionContext(realm);
        GlobalEnvironmentRecord envRec = new GlobalEnvironmentRecord(defaultContext, globalThis);
        LexicalEnvironment globalEnv = new LexicalEnvironment(defaultContext, envRec);

        //
        realm.globalThis = globalThis;
        realm.globalEnv = globalEnv;
        realm.defaultContext = defaultContext;
        realm.options = EnumSet.copyOf(options);<commit_msg>Compute locale specific list separator string<commit_after>/**
 * Copyright (c) 2012-2013 <NAME>
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */
package com.github.anba.es6draft.runtime;

import static com.github.anba.es6draft.runtime.AbstractOperations.Get;
import static com.github.anba.es6draft.runtime.ExecutionContext.newScriptExecutionContext;

import java.text.Collator;
import java.text.DecimalFormatSymbols;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;

import com.github.anba.es6draft.runtime.internal.CompatibilityOption;
import com.github.anba.es6draft.runtime.internal.Messages;
import com.github.anba.es6draft.runtime.internal.ObjectAllocator;
import com.github.anba.es6draft.runtime.modules.Loader;
import com.github.anba.es6draft.runtime.objects.*;
import com.github.anba.es6draft.runtime.objects.NativeErrorConstructor.ErrorType;
import com.github.anba.es6draft.runtime.objects.binary.ArrayBufferConstructor;
import com.github.anba.es6draft.runtime.objects.binary.ArrayBufferPrototype;
import com.github.anba.es6draft.runtime.objects.binary.DataViewConstructor;
import com.github.anba.es6draft.runtime.objects.binary.DataViewPrototype;
import com.github.anba.es6draft.runtime.objects.binary.ElementType;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayConstructor;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayConstructorPrototype;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayPrototype;
import com.github.anba.es6draft.runtime.objects.binary.TypedArrayPrototypePrototype;
import com.github.anba.es6draft.runtime.objects.internal.ListIteratorPrototype;
import com.github.anba.es6draft.runtime.objects.intl.CollatorConstructor;
import com.github.anba.es6draft.runtime.objects.intl.CollatorPrototype;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatConstructor;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatPrototype;
import com.github.anba.es6draft.runtime.objects.intl.IntlObject;
import com.github.anba.es6draft.runtime.objects.intl.NumberFormatConstructor;
import com.github.anba.es6draft.runtime.objects.intl.NumberFormatPrototype;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorFunctionConstructor;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorFunctionPrototype;
import com.github.anba.es6draft.runtime.objects.iteration.GeneratorPrototype;
import com.github.anba.es6draft.runtime.objects.reflect.Reflect;
import com.github.anba.es6draft.runtime.types.Callable;
import com.github.anba.es6draft.runtime.types.Intrinsics;
import com.github.anba.es6draft.runtime.types.ScriptObject;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryFunction;

/**
 * <h1>10 Executable Code and Execution Contexts</h1>
 * <ul>
 * <li>10.3 Code Realms
 * </ul>
 */
public class Realm {
    /**
     * [[intrinsics]]
     */
    private Map<Intrinsics, ScriptObject> intrinsics = new EnumMap<>(Intrinsics.class);

    /**
     * [[globalThis]]
     */
    private GlobalObject globalThis;

    /**
     * [[globalEnv]]
     */
    private LexicalEnvironment globalEnv;

    /**
     * [[loader]]
     */
    private Loader loader;

    /**
     * [[ThrowTypeError]]
     */
    private Callable throwTypeError;

    private Callable builtinEval;

    private ExecutionContext defaultContext;

    private Set<CompatibilityOption> options;

    private Locale locale = Locale.getDefault();
    private TimeZone timezone = TimeZone.getDefault();
    private Messages messages = Messages.create(locale);

    // TODO: move into function source object
    private Map<String, ScriptObject> templateCallSites = new HashMap<>();

    private Realm() {
    }

    /**
     * [[intrinsics]]
     */
    public ScriptObject getIntrinsic(Intrinsics id) {
        return intrinsics.get(id);
    }

    /**
     * [[globalThis]]
     */
    public GlobalObject getGlobalThis() {
        return globalThis;
    }

    /**
     * [[globalEnv]]
     */
    public LexicalEnvironment getGlobalEnv() {
        return globalEnv;
    }

    /**
     * [[loader]]
     */
    public Loader getLoader() {
        return loader;
    }

    /**
     * [[ThrowTypeError]]
     */
    public Callable getThrowTypeError() {
        assert throwTypeError != null : "throwTypeError not yet initialised";
        return throwTypeError;
    }

    /**
     * Returns the default execution context for this realm
     */
    public ExecutionContext defaultContext() {
        return defaultContext;
    }

    private AtomicInteger evalCounter = new AtomicInteger(0);
    private AtomicInteger functionCounter = new AtomicInteger(0);

    /**
     * Next class name for eval scripts
     * 
     * @see Eval
     */
    public String nextEvalName() {
        return "Eval_" + evalCounter.incrementAndGet();
    }

    /**
     * Next class name for functions
     * 
     * @see FunctionConstructor
     * @see GeneratorFunctionConstructor
     */
    public String nextFunctionName() {
        return "Function_" + functionCounter.incrementAndGet();
    }

    /**
     * Returns this realm's locale
     */
    public Locale getLocale() {
        return locale;
    }

    /**
     * Returns this realm's timezone
     */
    public TimeZone getTimezone() {
        return timezone;
    }

    /**
     * Returns the localised message for {@code key}
     */
    public String message(Messages.Key key) {
        return messages.getString(key);
    }

    /**
     * Returns a reference to the built-in <code>eval</code> function
     */
    public Callable getBuiltinEval() {
        return builtinEval;
    }

    /**
     * Returns the compatibility options for this realm instance
     */
    public Set<CompatibilityOption> getOptions() {
        return options;
    }

    public boolean isEnabled(CompatibilityOption option) {
        return options.contains(option);
    }

    /**
     * Returns the template call-site object for {@code key}
     */
    public ScriptObject getTemplateCallSite(String key) {
        return templateCallSites.get(key);
    }

    /**
     * Stores the template call-site object
     */
    public void addTemplateCallSite(String key, ScriptObject callSite) {
        templateCallSites.put(key, callSite);
    }

    /**
     * Returns a {@link Collator} for this realm's locale
     * 
     * @deprecated No longer used
     */
    @Deprecated
    public Collator getCollator() {
        Collator collator = Collator.getInstance(locale);
        // Use Normalised Form D for comparison (cf. 1192.168.3.11, Note 2)
        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
        // `"\u0001".localeCompare("\u0002") == -1` should yield true
        collator.setStrength(Collator.IDENTICAL);
        return collator;
    }

    /**
     * Returns the locale specific list separator
     */
    public String getListSeparator() {
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
        return symbols.getDecimalSeparator() == ',' ? ";" : ",";
    }

    private static final ObjectAllocator<GlobalObject> DEFAULT_GLOBAL_OBJECT = new ObjectAllocator<GlobalObject>() {
        @Override
        public GlobalObject newInstance(Realm realm) {
            return new GlobalObject(realm);
        }
    };

    public static Realm newRealm() {
        return newRealm(DEFAULT_GLOBAL_OBJECT, CompatibilityOption.WebCompatibility());
    }

    public static Realm newRealm(ObjectAllocator<? extends GlobalObject> allocator,
            Set<CompatibilityOption> options) {
        Realm realm = new Realm();
        GlobalObject globalThis = allocator.newInstance(realm);
        ExecutionContext defaultContext = newScriptExecutionContext(realm);
        GlobalEnvironmentRecord envRec = new GlobalEnvironmentRecord(defaultContext, globalThis);
        LexicalEnvironment globalEnv = new LexicalEnvironment(defaultContext, envRec);

        //
        realm.globalThis = globalThis;
        realm.globalEnv = globalEnv;
        realm.defaultContext = defaultContext;
        realm.options = EnumSet.copyOf(options);
{'fraction_non_alphanumeric': 0.10413112356812089, 'fraction_numerical': 0.008469412624908603, 'mean_word_length': 3.2731059619890654, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2557632', 'n_tokens_mistral': 4775, 'n_tokens_neox': 4685, 'n_words': 930}