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);