mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-22 09:29:38 +00:00
Fix issues with expressions not completing
Moved NumberBaseConverter into its own file
This commit is contained in:
@@ -20,96 +20,10 @@ const xpath = require('xpath');
|
||||
const { ADBClient } = require('./adbclient');
|
||||
const { Debugger } = require('./debugger');
|
||||
const $ = require('./jq-promise');
|
||||
const NumberBaseConverter = require('./nbc');
|
||||
const { D, isEmptyObject } = require('./util');
|
||||
const ws_proxy = require('./wsproxy').proxy.Server(6037, 5037);
|
||||
|
||||
// arbitrary precision helper class for 64 bit numbers
|
||||
const NumberBaseConverter = {
|
||||
// Adds two arrays for the given base (10 or 16), returning the result.
|
||||
add(x, y, base) {
|
||||
var z = [], n = Math.max(x.length, y.length), carry = 0, i = 0;
|
||||
while (i < n || carry) {
|
||||
var xi = i < x.length ? x[i] : 0;
|
||||
var yi = i < y.length ? y[i] : 0;
|
||||
var zi = carry + xi + yi;
|
||||
z.push(zi % base);
|
||||
carry = Math.floor(zi / base);
|
||||
i++;
|
||||
}
|
||||
return z;
|
||||
},
|
||||
// Returns a*x, where x is an array of decimal digits and a is an ordinary
|
||||
// JavaScript number. base is the number base of the array x.
|
||||
multiplyByNumber(num, x, base) {
|
||||
if (num < 0) return null;
|
||||
if (num == 0) return [];
|
||||
var result = [], power = x;
|
||||
for(;;) {
|
||||
if (num & 1) {
|
||||
result = this.add(result, power, base);
|
||||
}
|
||||
num = num >> 1;
|
||||
if (num === 0) return result;
|
||||
power = this.add(power, power, base);
|
||||
}
|
||||
},
|
||||
twosComplement(str, base) {
|
||||
const invdigits = str.split('').map(c => 15 - parseInt(c,base)).reverse();
|
||||
const negdigits = this.add(invdigits, [1], base).slice(0,str.length);
|
||||
return negdigits.reverse().map(d => d.toString(base)).join('');
|
||||
},
|
||||
convertBase(str, fromBase, toBase) {
|
||||
if (fromBase === 10 && /[eE]/.test(str)) {
|
||||
// convert exponents to a string of zeros
|
||||
var s = str.split(/[eE]/);
|
||||
str = s[0] + '0'.repeat(parseInt(s[1],10)); // works for 0/+ve exponent,-ve throws
|
||||
}
|
||||
var digits = str.split('').map(d => parseInt(d,fromBase)).reverse();
|
||||
var outArray = [], power = [1];
|
||||
for (var i = 0; i < digits.length; i++) {
|
||||
if (digits[i]) {
|
||||
outArray = this.add(outArray, this.multiplyByNumber(digits[i], power, toBase), toBase);
|
||||
}
|
||||
power = this.multiplyByNumber(fromBase, power, toBase);
|
||||
}
|
||||
return outArray.reverse().map(d => d.toString(toBase)).join('');
|
||||
},
|
||||
decToHex(decstr, minlen) {
|
||||
var res, isneg = decstr[0] === '-';
|
||||
if (isneg) decstr = decstr.slice(1)
|
||||
decstr = decstr.match(/^0*(.+)$/)[1]; // strip leading zeros
|
||||
if (decstr.length < 16 && !/[eE]/.test(decstr)) { // 16 = Math.pow(2,52).toString().length
|
||||
// less than 52 bits - just use parseInt
|
||||
res = parseInt(decstr, 10).toString(16);
|
||||
} else {
|
||||
res = NumberBaseConverter.convertBase(decstr, 10, 16);
|
||||
}
|
||||
if (isneg) {
|
||||
res = NumberBaseConverter.twosComplement(res, 16);
|
||||
if (/^[0-7]/.test(res)) res = 'f'+res; //msb must be set for -ve numbers
|
||||
} else if (/^[^0-7]/.test(res))
|
||||
res = '0' + res; // msb must not be set for +ve numbers
|
||||
if (minlen && res.length < minlen) {
|
||||
res = (isneg?'f':'0').repeat(minlen - res.length) + res;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
hexToDec(hexstr, signed) {
|
||||
var res, isneg = /^[^0-7]/.test(hexstr);
|
||||
if (hexstr.match(/^0*(.+)$/)[1].length*4 < 52) {
|
||||
// less than 52 bits - just use parseInt
|
||||
res = parseInt(hexstr, 16);
|
||||
if (signed && isneg) res = -res;
|
||||
return res.toString(10);
|
||||
}
|
||||
if (isneg) {
|
||||
hexstr = NumberBaseConverter.twosComplement(hexstr, 16);
|
||||
}
|
||||
res = (isneg ? '-' : '') + NumberBaseConverter.convertBase(hexstr, 16, 10);
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
// some commonly used Java types in debugger-compatible format
|
||||
const JTYPES = {
|
||||
byte: {name:'int',signature:'B'},
|
||||
@@ -1440,7 +1354,7 @@ class AndroidDebugSession extends DebugSession {
|
||||
local = { vtype:'literal',name:'',hasnullvalue:true,type:JTYPES.null,value:nullvalue,valid:true };
|
||||
break;
|
||||
case 'ident':
|
||||
if (!locals) reject_evaluation(`Cannot find variable: ${expr.root_term}`);
|
||||
if (!locals) return reject_evaluation(`Cannot find variable: ${expr.root_term}`);
|
||||
local = locals.find(l => l.name === expr.root_term);
|
||||
break;
|
||||
case 'number':
|
||||
|
||||
@@ -50,6 +50,8 @@ var Deferred = exports.Deferred = function(p, parent) {
|
||||
var res = this.fn.apply(this.def._context,a);
|
||||
if (res === undefined)
|
||||
return a;
|
||||
if (res && res._isdeferred)
|
||||
return res._promise;
|
||||
return res;
|
||||
}.bind({def:faildef,fn:fn}));
|
||||
faildef._promise = faildef._original = p;
|
||||
|
||||
89
src/nbc.js
Normal file
89
src/nbc.js
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
// arbitrary precision helper class for 64 bit numbers
|
||||
const NumberBaseConverter = {
|
||||
// Adds two arrays for the given base (10 or 16), returning the result.
|
||||
add(x, y, base) {
|
||||
var z = [], n = Math.max(x.length, y.length), carry = 0, i = 0;
|
||||
while (i < n || carry) {
|
||||
var xi = i < x.length ? x[i] : 0;
|
||||
var yi = i < y.length ? y[i] : 0;
|
||||
var zi = carry + xi + yi;
|
||||
z.push(zi % base);
|
||||
carry = Math.floor(zi / base);
|
||||
i++;
|
||||
}
|
||||
return z;
|
||||
},
|
||||
// Returns a*x, where x is an array of decimal digits and a is an ordinary
|
||||
// JavaScript number. base is the number base of the array x.
|
||||
multiplyByNumber(num, x, base) {
|
||||
if (num < 0) return null;
|
||||
if (num == 0) return [];
|
||||
var result = [], power = x;
|
||||
for(;;) {
|
||||
if (num & 1) {
|
||||
result = this.add(result, power, base);
|
||||
}
|
||||
num = num >> 1;
|
||||
if (num === 0) return result;
|
||||
power = this.add(power, power, base);
|
||||
}
|
||||
},
|
||||
twosComplement(str, base) {
|
||||
const invdigits = str.split('').map(c => base - 1 - parseInt(c,base)).reverse();
|
||||
const negdigits = this.add(invdigits, [1], base).slice(0,str.length);
|
||||
return negdigits.reverse().map(d => d.toString(base)).join('');
|
||||
},
|
||||
convertBase(str, fromBase, toBase) {
|
||||
if (fromBase === 10 && /[eE]/.test(str)) {
|
||||
// convert exponents to a string of zeros
|
||||
var s = str.split(/[eE]/);
|
||||
str = s[0] + '0'.repeat(parseInt(s[1],10)); // works for 0/+ve exponent,-ve throws
|
||||
}
|
||||
var digits = str.split('').map(d => parseInt(d,fromBase)).reverse();
|
||||
var outArray = [], power = [1];
|
||||
for (var i = 0; i < digits.length; i++) {
|
||||
if (digits[i]) {
|
||||
outArray = this.add(outArray, this.multiplyByNumber(digits[i], power, toBase), toBase);
|
||||
}
|
||||
power = this.multiplyByNumber(fromBase, power, toBase);
|
||||
}
|
||||
return outArray.reverse().map(d => d.toString(toBase)).join('');
|
||||
},
|
||||
decToHex(decstr, minlen) {
|
||||
var res, isneg = decstr[0] === '-';
|
||||
if (isneg) decstr = decstr.slice(1)
|
||||
decstr = decstr.match(/^0*(.+)$/)[1]; // strip leading zeros
|
||||
if (decstr.length < 16 && !/[eE]/.test(decstr)) { // 16 = Math.pow(2,52).toString(10).length
|
||||
// less than 52 bits - just use parseInt
|
||||
res = parseInt(decstr, 10).toString(16);
|
||||
} else {
|
||||
res = NumberBaseConverter.convertBase(decstr, 10, 16);
|
||||
}
|
||||
if (isneg) {
|
||||
res = NumberBaseConverter.twosComplement(res, 16);
|
||||
if (/^[0-7]/.test(res)) res = 'f'+res; //msb must be set for -ve numbers
|
||||
} else if (/^[^0-7]/.test(res))
|
||||
res = '0' + res; // msb must not be set for +ve numbers
|
||||
if (minlen && res.length < minlen) {
|
||||
res = (isneg?'f':'0').repeat(minlen - res.length) + res;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
hexToDec(hexstr, signed) {
|
||||
var res, isneg = /^[^0-7]/.test(hexstr);
|
||||
if (hexstr.match(/^0*(.+)$/)[1].length*4 < 52) {
|
||||
// less than 52 bits - just use parseInt
|
||||
res = parseInt(hexstr, 16);
|
||||
if (signed && isneg) res = -res;
|
||||
return res.toString(10);
|
||||
}
|
||||
if (isneg) {
|
||||
hexstr = NumberBaseConverter.twosComplement(hexstr, 16);
|
||||
}
|
||||
res = (isneg ? '-' : '') + NumberBaseConverter.convertBase(hexstr, 16, 10);
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
Object.assign(exports, NumberBaseConverter);
|
||||
Reference in New Issue
Block a user