<commit_before>/* See license.txt for terms of usage */
/*jshint esnext:true, es5:true, curly:false */
/*global FBTrace:true, Components:true, Proxy:true, define:true */

// A note on terminology: here a "closure"/"environment" is generally thought
// of as a container of "scopes".

define([
    "firebug/firebug",
    "firebug/lib/wrapper"
],
function(Firebug, Wrapper) {
"use strict";

// ********************************************************************************************* //
// Constants

const Cu = Components.utils;

const ScopeProxy = function() {};
const OptimizedAway = Object.create(null);
Object.freeze(OptimizedAway);

// ********************************************************************************************* //

var ClosureInspector =
{
    hasInit: false,
    Debugger: null,
    debuggeeCache: new WeakMap(),

    getInactiveDebuggerForContext: function(context)
    {
        if (context.inactiveDebugger)
            return context.inactiveDebugger;

        if (!this.hasInit)
        {
            this.hasInit = true;
            try
            {
                Cu.import("resource://gre/modules/jsdebugger.jsm");
                window.addDebuggerToGlobal(window);
                this.Debugger = window.Debugger;
            }
            catch (exc)
            {
                if (FBTrace.DBG_COMMANDLINE)
                    FBTrace.sysout("ClosureInspector; Debugger not found", exc);
            }
        }
        if (!this.Debugger)
            return;

        var dbg = new this.Debugger();
        dbg.enabled = false;
        context.inactiveDebugger = dbg;
        return dbg;
    },

    getDebuggeeObject: function(context, global)
    {
        var dbg = this.getInactiveDebuggerForContext(context);

        var dglobal = this.debuggeeCache.get(global);
        if (dglobal)
            return dglobal;

        // Note: for no purposes is it actually important that the global is
        // held as a debuggee; it just makes things slower.
        dglobal = dbg.addDebuggee(global);
        dbg.removeDebuggee(global);

        this.debuggeeCache.set(global, dglobal);
        return dglobal;
    },

    getVariableOrOptimizedAway: function(scope, name)
    {
        try
        {
            var ret = scope.getVariable(name);
            if (ret !== undefined)
                return ret;

            if (scope.type === "declarative")
            {
                // The variable is either optimized away or actually set to
                // undefined. Optimized-away ones are apparently not settable,
                // so try to detect them by that (it seems rather safe).
                scope.setVariable(name, 0);
                if (scope.getVariable(name) === undefined)
                    return OptimizedAway;
                scope.setVariable(name, undefined);
            }

            return undefined;
        }
        catch (exc)
        {
            // E.g. optimized-away "arguments" can throw "Debugger scope is not live".
            if (FBTrace.DBG_COMMANDLINE)<commit_msg>Follow up fix<commit_after>/* See license.txt for terms of usage */
/*jshint esnext:true, es5:true, curly:false */
/*global FBTrace:true, Components:true, Proxy:true, define:true */

// A note on terminology: here a "closure"/"environment" is generally thought
// of as a container of "scopes".

define([
    "firebug/firebug",
    "firebug/lib/wrapper"
],
function(Firebug, Wrapper) {
"use strict";

// ********************************************************************************************* //
// Constants

const Cu = Components.utils;

const ScopeProxy = function() {};
const OptimizedAway = Object.create(null);
Object.freeze(OptimizedAway);

// ********************************************************************************************* //

var ClosureInspector =
{
    hasInit: false,
    Debugger: null,
    debuggeeCache: new WeakMap(),

    getInactiveDebuggerForContext: function(context)
    {
        if (context.inactiveDebugger)
            return context.inactiveDebugger;

        if (!this.hasInit)
        {
            this.hasInit = true;
            try
            {
                Cu.import("resource://gre/modules/jsdebugger.jsm");
                window.addDebuggerToGlobal(window);
                this.Debugger = window.Debugger;
            }
            catch (exc)
            {
                if (FBTrace.DBG_COMMANDLINE)
                    FBTrace.sysout("ClosureInspector; Debugger not found", exc);
            }
        }
        if (!this.Debugger)
            return;

        var dbg = new this.Debugger();
        dbg.enabled = false;
        context.inactiveDebugger = dbg;
        return dbg;
    },

    getDebuggeeObject: function(context, global)
    {
        var dbg = this.getInactiveDebuggerForContext(context);

        // Because (outer) windows persist between reloads, use their documents
        // as keys into the cache instead.
        var cacheKey = global.document || global;

        var dglobal = this.debuggeeCache.get(cacheKey);
        if (dglobal)
            return dglobal;

        // Note: for no purposes is it actually important that the global is
        // held as a debuggee; it just makes things slower.
        dglobal = dbg.addDebuggee(global);
        dbg.removeDebuggee(global);

        this.debuggeeCache.set(cacheKey, dglobal);
        return dglobal;
    },

    getVariableOrOptimizedAway: function(scope, name)
    {
        try
        {
            var ret = scope.getVariable(name);
            if (ret !== undefined)
                return ret;

            if (scope.type === "declarative")
            {
                // The variable is either optimized away or actually set to
                // undefined. Optimized-away ones are apparently not settable,
                // so try to detect them by that (it seems rather safe).
                scope.setVariable(name, 0);
                if (scope.getVariable(name) === undefined)
                    return OptimizedAway;
                scope.setVariable(name, undefined);
            }

            return undefined;
        }
        catch (exc)
        {
            // E.g. optimized-away "arguments" can throw "Debugger scope is not live".
            if (FBTrace.DBG_COMMANDLINE)
{'fraction_non_alphanumeric': 0.15366317792578496, 'fraction_numerical': 0.0006343165239454488, 'mean_word_length': 1.9961995249406175, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, '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': '2555275', 'n_tokens_mistral': 1709, 'n_tokens_neox': 1645, 'n_words': 430}