github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/test/test_esprima.js (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  var esprima = require('../lib/esprima.js');
    20  
    21  var source = "'use strict';\nvar SampleContract = function() {\n    LocalContractStorage.defineProperties(this, {\n        name: null,\n        count: null\n    });\n    LocalContractStorage.defineMapProperty(this, \"allocation\" + 123);\n    this.a = 0;\n};";
    22  var x = "\nSampleContract.prototype = {\n    init: function(name, count, allocation) {\n        this.name = name;\n        this.count = count;\n        allocation.forEach(function(item) {\n            this.allocation.put(item.name, item.count);\n        }, this);\n    },\n    dump: function() {\n        console.log('dump: this.name = ' + this.name);\n        console.log('dump: this.count = ' + this.count);\n        return this.a;\n    },\n    incr: function() {\n        this.a++;\n        var z = this.a;\n        console.log(this.dump());\n        return this.a;\n    },\n    verify: function(expectedName, expectedCount, expectedAllocation) {\n        if (!Object.is(this.name, expectedName)) {\n            throw new Error(\"name is not the same, expecting \" + expectedName + \", actual is \" + this.name + \".\");\n        }\n        if (!Object.is(this.count, expectedCount)) {\n            throw new Error(\"count is not the same, expecting \" + expectedCount + \", actual is \" + this.count + \".\");\n        }\n        expectedAllocation.forEach(function(expectedItem) {\n            var count = this.allocation.get(expectedItem.name);\n            if (!Object.is(count, expectedItem.count)) {\n                throw new Error(\"count of \" + expectedItem.name + \" is not the same, expecting \" + expectedItem.count + \", actual is \" + count + \".\");\n            }\n        }, this);\n    }\n};\nmodule.exports = SampleContract;";
    23  source += x;
    24  
    25  var dump_meta = function (meta) {
    26      for (var k in meta) {
    27          console.log('meta[' + k + ']=' + meta[k]);
    28          for (var kk in meta[k]) {
    29              console.log('meta[' + k + '][' + kk + ']=' + meta[k][kk]);
    30          }
    31      }
    32  };
    33  
    34  // var ast = esprima.parseScript(source, {
    35  //     range: true,
    36  //     loc: true
    37  // }, function (node, meta) {
    38  //     console.log('node.type=' + node.type);
    39  
    40  //     var code = source.slice(meta.start.offset, meta.end.offset);
    41  //     console.log('code is ' + code);
    42  
    43  //     console.log('------------------');
    44  // });
    45  // console.log(ast);
    46  
    47  var ast = esprima.parseScript(source, {
    48      range: true,
    49      loc: true
    50  });
    51  
    52  // console.log(ast);
    53  
    54  function traverse(object, visitor, master, key) {
    55      var key, child, parent, path;
    56  
    57      parent = (typeof master === 'undefined') ? [] : master;
    58  
    59      if (visitor.call(null, object, parent, key) === false) {
    60          return;
    61      }
    62      for (key in object) {
    63          if (object.hasOwnProperty(key)) {
    64              child = object[key];
    65              path = [object];
    66              path.push.apply(path, parent);
    67              if (typeof child === 'object' && child !== null) {
    68                  traverse(child, visitor, path, key);
    69              }
    70          }
    71      }
    72  };
    73  
    74  var flag = 1;
    75  
    76  var exprStmts = new Map();
    77  
    78  function InstructionInc_v01(val, path) {
    79      // console.log('path.len = ' + path.length);
    80      for (var i = 0; i < path.length; i++) {
    81          var item = path[i];
    82          if (!item.hasOwnProperty('type')) {
    83              console.log('typeof item is ' + typeof item);
    84              // console.log(item);
    85          } else {
    86              var node = item;
    87              console.log('node.type = ' + node.type);
    88              if (node.type == "ExpressionStatement") {
    89                  // console.log('inst++');
    90                  if (!node.hasOwnProperty('inst_flag')) {
    91                      node.inst_flag = "flag-" + flag;
    92                      flag++;
    93                      console.log('set flag ' + node.inst_flag);
    94                      exprStmts[node.inst_flag] = node;
    95                  }
    96                  if (!node.hasOwnProperty("inst_counter")) {
    97                      node.inst_counter = 0;
    98                  }
    99                  node.inst_counter += val;
   100                  return;
   101              }
   102          }
   103      }
   104  };
   105  
   106  var ParentExpr = {
   107      ExpressionStatement: 1,
   108      BlockStatement: 1,
   109      IfStatement: 1,
   110      SwitchStatement: 1,
   111      DoWhileStatement: 1,
   112      ForStatement: 1,
   113      ForInStatement: 1,
   114      ForOfStatement: 1,
   115      WhileStatement: 1,
   116      WithStatement: 1,
   117      _XXX: 0
   118  };
   119  
   120  function InstructionInc(val, path) {
   121      for (var i = 0; i < path.length; i++) {
   122          var node = path[i];
   123          if (!node.hasOwnProperty('type')) {
   124              continue;
   125          }
   126  
   127          if (node.type in ParentExpr) {
   128              // console.log('inst++');
   129              if (!node.hasOwnProperty('inst_flag')) {
   130                  node.inst_flag = "flag-" + flag;
   131                  flag++;
   132                  console.log('set flag ' + node.inst_flag);
   133                  exprStmts[node.inst_flag] = node;
   134              }
   135              if (!node.hasOwnProperty("inst_counter")) {
   136                  node.inst_counter = 0;
   137              }
   138              node.inst_counter += val;
   139              break;
   140          }
   141      }
   142  };
   143  
   144  var InstMap = {
   145      CallExpression: 1,
   146      AssignmentExpression: 1,
   147      BinaryExpression: 1,
   148      UpdateExpression: 1,
   149      UnaryExpression: 1,
   150      LogicalExpression: 1,
   151      _XXX: 0
   152  };
   153  
   154  traverse(ast, function (node, path, key) {
   155      if (node.hasOwnProperty('range')) {
   156          if (node.range[0] == 318 && node.range[1] == 334) {
   157              debugger;
   158              console.log('318-334: ' + path);
   159          }
   160      }
   161      if ((node.type in InstMap)) {
   162          // if (node.type == 'BinaryExpression') {
   163          //     for (var i = 0; i < path.length; i++) {
   164          //         console.log(i + ' : ' + typeof (path[i]));
   165          //     }
   166          // }
   167          console.log('--------------------');
   168          console.log('found expr ' + node.type + '; key is ' + key);
   169          InstructionInc(InstMap[node.type], path);
   170      } else if (node.type == 'FunctionExpression') {
   171          // console.log('FunctionExpression: node.params = ' + JSON.stringify(node.params));
   172      }
   173  });
   174  
   175  var new_source = "";
   176  var start_offset = 0;
   177  // traverse(ast, function (node, path) {
   178  //     if (node.hasOwnProperty('range')) {
   179  //         if (node.range[0] == 318 && node.range[1] == 335) {
   180  //             debugger;
   181  //         }
   182  //     }
   183  //     if (node.type == "ExpressionStatement") {
   184  //         if (node.hasOwnProperty("inst_counter")) {
   185  //             console.log('ExpressionStatement: {flag: ' + node.inst_flag + ', count: ' + node.inst_counter + '}.');
   186  //             console.log('source scope: ' + node.range);
   187  //             new_source += source.slice(start_offset, node.range[1]) + "\ninstruction_counter.incr('" + node.inst_flag + "', " + node.inst_counter + ");\n";
   188  //             start_offset = node.range[1];
   189  //         }
   190  //     }
   191  // });
   192  // new_source += source.slice(start_offset);
   193  
   194  var ranges = [];
   195  for (var key in exprStmts) {
   196      ranges.push({
   197          offset: exprStmts[key].range[0],
   198          count: exprStmts[key].inst_counter,
   199          flag: exprStmts[key].inst_flag
   200      });
   201  }
   202  ranges.sort(function (a, b) {
   203      return a.offset - b.offset;
   204  });
   205  console.log(ranges);
   206  
   207  ranges.forEach(function (item) {
   208      // console.log('!!!!!!!!!!!!!!!');
   209      // console.log('from {' + start_offset + ', ' + item.end_offset + '}');
   210      var c = source.slice(start_offset, item.offset);
   211      // console.log(c);
   212      new_source += source.slice(start_offset, item.offset);
   213      new_source += 'instruction_counter("' + item.flag + '",' + item.count + ');\n';
   214      start_offset = item.offset;
   215  });
   216  new_source += source.slice(start_offset);
   217  
   218  console.log(new_source);