michael@0: /* -*- Mode: Javascript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: michael@0: "use strict"; michael@0: michael@0: function assert(x, msg) michael@0: { michael@0: if (x) michael@0: return; michael@0: debugger; michael@0: if (msg) michael@0: throw "assertion failed: " + msg + "\n" + (Error().stack); michael@0: else michael@0: throw "assertion failed: " + (Error().stack); michael@0: } michael@0: michael@0: function defined(x) { michael@0: return x !== undefined; michael@0: } michael@0: michael@0: function xprint(x, padding) michael@0: { michael@0: if (!padding) michael@0: padding = ""; michael@0: if (x instanceof Array) { michael@0: print(padding + "["); michael@0: for (var elem of x) michael@0: xprint(elem, padding + " "); michael@0: print(padding + "]"); michael@0: } else if (x instanceof Object) { michael@0: print(padding + "{"); michael@0: for (var prop in x) { michael@0: print(padding + " " + prop + ":"); michael@0: xprint(x[prop], padding + " "); michael@0: } michael@0: print(padding + "}"); michael@0: } else { michael@0: print(padding + x); michael@0: } michael@0: } michael@0: michael@0: function sameBlockId(id0, id1) michael@0: { michael@0: if (id0.Kind != id1.Kind) michael@0: return false; michael@0: if (!sameVariable(id0.Variable, id1.Variable)) michael@0: return false; michael@0: if (id0.Kind == "Loop" && id0.Loop != id1.Loop) michael@0: return false; michael@0: return true; michael@0: } michael@0: michael@0: function sameVariable(var0, var1) michael@0: { michael@0: assert("Name" in var0 || var0.Kind == "This" || var0.Kind == "Return"); michael@0: assert("Name" in var1 || var1.Kind == "This" || var1.Kind == "Return"); michael@0: if ("Name" in var0) michael@0: return "Name" in var1 && var0.Name[0] == var1.Name[0]; michael@0: return var0.Kind == var1.Kind; michael@0: } michael@0: michael@0: function blockIdentifier(body) michael@0: { michael@0: if (body.BlockId.Kind == "Loop") michael@0: return body.BlockId.Loop; michael@0: assert(body.BlockId.Kind == "Function", "body.Kind should be Function, not " + body.BlockId.Kind); michael@0: return body.BlockId.Variable.Name[0]; michael@0: } michael@0: michael@0: function collectBodyEdges(body) michael@0: { michael@0: body.predecessors = []; michael@0: body.successors = []; michael@0: if (!("PEdge" in body)) michael@0: return; michael@0: michael@0: for (var edge of body.PEdge) { michael@0: var [ source, target ] = edge.Index; michael@0: if (!(target in body.predecessors)) michael@0: body.predecessors[target] = []; michael@0: body.predecessors[target].push(edge); michael@0: if (!(source in body.successors)) michael@0: body.successors[source] = []; michael@0: body.successors[source].push(edge); michael@0: } michael@0: } michael@0: michael@0: function getPredecessors(body) michael@0: { michael@0: try { michael@0: if (!('predecessors' in body)) michael@0: collectBodyEdges(body); michael@0: } catch (e) { michael@0: debugger; michael@0: printErr("body is " + body); michael@0: } michael@0: return body.predecessors; michael@0: } michael@0: michael@0: function getSuccessors(body) michael@0: { michael@0: if (!('successors' in body)) michael@0: collectBodyEdges(body); michael@0: return body.successors; michael@0: } michael@0: michael@0: // Split apart a function from sixgill into its mangled and unmangled name. If michael@0: // no mangled name was given, use the unmangled name as its mangled name michael@0: function splitFunction(func) michael@0: { michael@0: var split = func.indexOf("|"); michael@0: if (split == -1) michael@0: return [ func, func ]; michael@0: return [ func.substr(0, split), func.substr(split+1) ]; michael@0: } michael@0: michael@0: function mangled(fullname) michael@0: { michael@0: var split = fullname.indexOf("|"); michael@0: if (split == -1) michael@0: return fullname; michael@0: return fullname.substr(0, split); michael@0: } michael@0: michael@0: function readable(fullname) michael@0: { michael@0: var split = fullname.indexOf("|"); michael@0: if (split == -1) michael@0: return fullname; michael@0: return fullname.substr(split+1); michael@0: } michael@0: michael@0: function xdbLibrary() michael@0: { michael@0: var lib = ctypes.open(environment['XDB']); michael@0: return { michael@0: open: lib.declare("xdb_open", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr), michael@0: min_data_stream: lib.declare("xdb_min_data_stream", ctypes.default_abi, ctypes.int), michael@0: max_data_stream: lib.declare("xdb_max_data_stream", ctypes.default_abi, ctypes.int), michael@0: read_key: lib.declare("xdb_read_key", ctypes.default_abi, ctypes.char.ptr, ctypes.int), michael@0: read_entry: lib.declare("xdb_read_entry", ctypes.default_abi, ctypes.char.ptr, ctypes.char.ptr), michael@0: free_string: lib.declare("xdb_free", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr) michael@0: }; michael@0: }