Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/devtools/rootAnalysis/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  dumpCFG.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


// const cfg = loadCFG(scriptArgs[0]);
// dump_CFG(cfg);

function loadCFG(filename) {
  const data = os.file.readFile(filename);
  return JSON.parse(data);
}

function dump_CFG(cfg) {
  for (const body of cfg)
    dump_body(body);
}

function dump_body(body, src, dst) {
  const {BlockId,Command,DefineVariable,Index,Location,PEdge,PPoint,Version} = body;

  const [mangled, unmangled] = splitFunction(BlockId.Variable.Name[0]);
  print(`${unmangled} at ${Location[0].CacheString}:${Location[0].Line}`);

  if (src === undefined) {
    for (const def of DefineVariable)
      print(str_definition(def));
    print("");
  }

  for (const edge of PEdge) {
    if (src === undefined || edge.Index[0] == src) {
      if (dst == undefined || edge.Index[1] == dst)
        print(str_edge(edge, body));
    }
  }
}

function str_definition(def) {
  const {Type, Variable} = def;
  return `define ${str_Variable(Variable)} : ${str_Type(Type)}`;
}

function badFormat(what, val) {
  printErr("Bad format of " + what + ": " + JSON.stringify(val, null, 4));
  printErr((new Error).stack);
}

function str_Variable(variable) {
  if (variable.Kind == 'Return')
    return '';
  else if (variable.Kind == 'This')
    return 'this';

  try {
    return variable.Name[1];
  } catch(e) {
    badFormat("variable", variable);
  }
}

function str_Type(type) {
  try {
    const {Kind, Type, Name, TypeFunctionArguments} = type;
    if (Kind == 'Pointer')
      return str_Type(Type) + ["*""&""&&"][type.Reference];
    else if (Kind == 'CSU')
      return Name;
    else if (Kind == 'Array')
      return str_Type(Type) + "[]";
    else if (Kind == 'Function')
      return str_Type(Type) + "()";

    return Kind;
  } catch(e) {
    badFormat("type", type);
  }
}

var OpCodeNames = {
  'LessEqual': ['<=''>'],
  'LessThan': ['<''>='],
  'GreaterEqual': ['>=''<'],
  'Greater': ['>''<='],
  'Plus''+',
  'Minus''-',
};

function opcode_name(opcode, invert) {
  if (opcode in OpCodeNames) {
    const name = OpCodeNames[opcode];
    if (invert === undefined)
      return name;
    return name[invert ? 1 : 0];
  } else {
    if (invert === undefined)
      return opcode;
    return (invert ? '!' : '') + opcode;
  }
}

function str_value(val, env, options) {
  const {Kind, Variable, String, Exp} = val;
  if (Kind == 'Var')
    return str_Variable(Variable);
  else if (Kind == 'Drf') {
    // Suppress the vtable lookup dereference
    if (Exp[0].Kind == 'Fld' && "FieldInstanceFunction" in Exp[0].Field)
      return str_value(Exp[0], env);
    const exp = str_value(Exp[0], env);
    if (options && options.noderef)
      return exp;
    return "*" + exp;
  } else if (Kind == 'Fld') {
    const {Exp, Field} = val;
    const name = Field.Name[0];
    if ("FieldInstanceFunction" in Field) {
      return Field.FieldCSU.Type.Name + "." + name;
    }
    const container = str_value(Exp[0]);
    if (container.startsWith("*"))
      return container.substring(1) + "->" + name;
    return container + "." + name;
  } else if (Kind == 'Empty') {
    return '';
  } else if (Kind == 'Binop') {
    const {OpCode} = val;
    const op = opcode_name(OpCode);
    return `${str_value(Exp[0], env)} ${op} ${str_value(Exp[1], env)}`;
  } else if (Kind == 'Unop') {
    const exp = str_value(Exp[0], env);
    const {OpCode} = val;
    if (OpCode == 'LogicalNot')
      return `not ${exp}`;
    return `${OpCode}(${exp})`;
  } else if (Kind == 'Index') {
    const index = str_value(Exp[1], env);
    if (Exp[0].Kind == 'Drf')
      return `${str_value(Exp[0], env, {noderef:true})}[${index}]`;
    else
      return `&${str_value(Exp[0], env)}[${index}]`;
  } else if (Kind == 'NullTest') {
    return `nullptr == ${str_value(Exp[0], env)}`;
  } else if (Kind == "String") {
    return '"' + String + '"';
  } else if (String !== undefined) {
    return String;
  }
  badFormat("value", val);
}

function str_thiscall_Exp(exp) {
  return exp.Kind == 'Drf' ? str_value(exp.Exp[0]) + "->" : str_value(exp) + ".";
}

function stripcsu(s) {
    return s.replace("class """).replace("struct """).replace("union ");
}

function str_call(prefix, edge, env) {
  const {Exp, Type, PEdgeCallArguments, PEdgeCallInstance} = edge;
  const {Kind, Type:cType, TypeFunctionArguments, TypeFunctionCSU} = Type;

  if (Kind == 'Function') {
    const params = PEdgeCallArguments ? PEdgeCallArguments.Exp : [];
    const strParams = params.map(str_value);

    let func;
    let comment = "";
    let assign_exp;
    if (PEdgeCallInstance) {
      const csu = TypeFunctionCSU.Type.Name;
      const method = str_value(Exp[0], env);

      // Heuristic to only display the csu for constructors
      if (csu.includes(method)) {
        func = stripcsu(csu) + "::" + method;
      } else {
        func = method;
        comment = "# " + csu + "::" + method + "\n";
      }

      const {Exp: thisExp} = PEdgeCallInstance;
      func = str_thiscall_Exp(thisExp) + func;
    } else {
      func = str_value(Exp[0]);
    }
    assign_exp = Exp[1];

    let assign = "";
    if (assign_exp) {
      assign = str_value(assign_exp) + " := ";
    }
    return `${comment}${prefix} Call ${assign}${func}(${strParams.join(", ")})`;
  }

  print(JSON.stringify(edge, null, 4));
  throw new Error("unhandled format error");
}

function str_assign(prefix, edge) {
  const {Exp} = edge;
  const [lhs, rhs] = Exp;
  return `${prefix} Assign ${str_value(lhs)} := ${str_value(rhs)}`;
}

function str_loop(prefix, edge) {
  const {BlockId: {Loop}} = edge;
  return `${prefix} Loop ${Loop}`;
}

function str_assume(prefix, edge) {
  const {Exp, PEdgeAssumeNonZero} = edge;
  const cmp = PEdgeAssumeNonZero ? "" : "!";

  const {Exp: aExp, Kind, OpCode} = Exp[0];
  if (Kind == 'Binop') {
    const [lhs, rhs] = aExp;
    const op = opcode_name(OpCode, !PEdgeAssumeNonZero);
    return `${prefix} Assume ${str_value(lhs)} ${op} ${str_value(rhs)}`;
  } else if (Kind == 'Unop') {
    return `${prefix} Assume ${cmp}${OpCode} ${str_value(aExp[0])}`;
  } else if (Kind == 'NullTest') {
    return `${prefix} Assume nullptr ${cmp}== ${str_value(aExp[0])}`;
  } else if (Kind == 'Drf') {
    return `${prefix} Assume ${cmp}${str_value(Exp[0])}`;
  }

  print(JSON.stringify(edge, null, 4));
  throw new Error("unhandled format error");
}

function str_edge(edge, env) {
  const {Index, Kind} = edge;
  const [src, dst] = Index;
  const prefix = `[${src},${dst}]`;

  if (Kind == "Call")
    return str_call(prefix, edge, env);
  if (Kind == 'Assign')
    return str_assign(prefix, edge);
  if (Kind == 'Assume')
    return str_assume(prefix, edge);
  if (Kind == 'Loop')
    return str_loop(prefix, edge);

  print(JSON.stringify(edge, null, 4));
  throw "unhandled edge type";
}

function str(unknown) {
  if ("Name" in unknown) {
    return str_Variable(unknown);
  } else if ("Index" in unknown) {
    // Note: Variable also has .Index, with a different meaning.
    return str_edge(unknown);
  } else if ("Type" in unknown) {
    if ("Variable" in unknown) {
      return str_definition(unknown);
    } else {
      return str_Type(unknown);
    }
  } else if ("Kind" in unknown) {
    if ("BlockId" in unknown)
      return str_Variable(unknown);
    return str_value(unknown);
  }
  return "unknown";
}

function jdump(x) {
  print(JSON.stringify(x, null, 4));
  quit(0);
}

96%


¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.