{"size": 5313, "ext": "js", "max_stars_repo_path": "node_modules/llvm/src/library.js", "max_stars_repo_name": "djungelorm/llmv-opt-inference", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "node_modules/llvm/src/library.js", "max_issues_repo_name": "djungelorm/llmv-opt-inference", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "node_modules/llvm/src/library.js", "max_forks_repo_name": "djungelorm/llmv-opt-inference", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 27.3865979381, "max_line_length": 97, "alphanum_fraction": 0.6549971767}
var fs = require('fs');
var crypto = require('crypto');
var child_process = require('child_process');

var executableCache = undefined;
var executableCacheDir = 'cache';
var executableCachePath = executableCacheDir+'/program';

var hashProgram = function (program) {
  return crypto.createHash('sha256').update(compileInstrs(program)).digest('hex');
};

var loadExecutableCache = function () {
  console.log('loading exe cache');
  var cache = {};
  var files = fs.readdirSync(executableCacheDir);
  for (var file of files) {
    if (file.endsWith('.exe')) {
      var path = executableCacheDir + '/' + file;
      var hash = file.substring(executableCachePath.length, file.length-4);
      cache[hash] = path;
    }
  }
  return cache;
};

var resultsCache = {};

var runTests = function(program, tests) {
  var key = hashProgram(program);
  if (key in resultsCache)
    return resultsCache[key];
  var results = [];

  var exe = compileExecutable(program);
  var args = [program.inputs];
  for (var test of tests)
    args = args.concat(test);

  var p = child_process.spawnSync('./'+exe, args);
  if (p.stdout.length == 0 || p.status != 0)
    return undefined;

  var output = p.stdout.toString().trim().split(' ');
  for (var i = 0; i < output.length/2; i++) {
    results.push({
      'output': parseInt(output[i*2]),
      'output-binary': output[(i*2)+1]
    });
  }

  resultsCache[key] = results;
  return results;
};

var run = function(program, inputs) {
  var exe = compileExecutable(program);
  var stdout = child_process.execSync('./'+exe+' '+inputs.join(' '));
  return parseInt(stdout.toString());
};

var compileExecutable = function(program) {
  var key = hashProgram(program);
  var path = executableCachePath+'-'+key;
  var exePath = path+'.exe';

  if (executableCache === undefined)
    executableCache = loadExecutableCache();

  // If exists in in-memory cache
  if (key in executableCache)
    return executableCache[key];

  // Compile the program
  fs.writeFileSync(path+'.instrs', compileInstrs(program));
  child_process.execSync('bin/compile '+path);

  // Add to in-memory cache
  executableCache[key] = exePath;
  return exePath;
};

var compileInstrs = function(program) {
  var code = [program.inputs];
  for (var instr of program.instrs)
    code.push((instr.result ? instr.result+' ' : '') +
              instr.opcode+' '+instr.operands.join(' '));
  return code.join('\n')+'\n';
};

var compileIR = function(program) {
  var code = [];
  for (var instr of program.instrs)
    code.push((instr.result ? instr.result+' = ' : '') +
              instr.opcode+' i32 '+instr.operands.join(', '));
  return code.join('\n')+'\n';
};

var createProgram = function(inputs, instrs) {
  return {'inputs': inputs, 'instrs': instrs};
};

var createInstr = function(result, opcode, operands) {
  return {'result': result, 'opcode': opcode, 'operands': operands};
};

var getInstr = function(program, idx) {
  return program.instrs[idx];
};

var changeInstr = function(program, idx, newInstr) {
  if (idx == 0) {
    var last = program.instrs.slice(idx+1);
    var newInstrs = [newInstr].concat(last);
  } else if (idx == program.instrs.length-1) {
    var first = program.instrs.slice(0,idx);
    var newInstrs = first.concat(newInstr);
  } else {
    var first = program.instrs.slice(0,idx);
    var last = program.instrs.slice(idx+1);
    var newInstrs = first.concat(newInstr).concat(last);
  }
  return createProgram(program.inputs, newInstrs);
};

var addInstr = function(program, idx, newInstr) {
  if (idx == 0) {
    var newInstrs = [newInstr].concat(program.instrs);
  } else if (idx == program.instrs.length) {
    var newInstrs = program.instrs.concat(newInstr);
  } else {
    var first = program.instrs.slice(0,idx);
    var last = program.instrs.slice(idx);
    var newInstrs = first.concat(newInstr).concat(last);
  }
  return createProgram(program.inputs, newInstrs);
};

var removeInstr = function(program, idx) {
  if (idx == 0) {
    var newInstrs = program.instrs.slice(idx+1);
  } else if (idx == program.instrs.length-1) {
    var newInstrs = program.instrs.slice(0,idx);
  } else {
    var first = program.instrs.slice(0,idx);
    var last = program.instrs.slice(idx+1);
    var newInstrs = first.concat(last);
  }
  return createProgram(program.inputs, newInstrs);
};

var hammingDistance = function (a,b) {
  var result = 0;
  for (var i = 0; i < a.length; i++) {
    result += (a[i] != b[i]) ? 1 : 0;
  }
  return result;
};

var pad = function (num) {
  var len = 8;
  var s = "000000000" + num;
  return s.substr(s.length-len);
};

var outputSamples = function (path, samples) {
  var i = 0;
  for (var sample of samples) {
    fs.writeFileSync(path+'/'+pad(i)+'.txt', 'text 40,80 "'+compileIR(sample.value.program)+'"');
    i++;
  }
  var data = ['latency'];
  for (var sample of samples) {
    data.push(sample.value.latency);
  }
  fs.writeFileSync(path+'/data.csv', data.join('\n'));
};

module.exports = {
  program: createProgram,
  instr: createInstr,
  getInstr: getInstr,
  changeInstr: changeInstr,
  addInstr: addInstr,
  removeInstr: removeInstr,
  runTests: runTests,
  run: run,
  compileExecutable: compileExecutable,
  compileInstrs: compileInstrs,
  compileIR: compileIR,
  hammingDistance: hammingDistance,
  outputSamples: outputSamples
};
