java-class-tools
Advanced tools
Comparing version
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
/*! | ||
@@ -9,3 +14,2 @@ * https://github.com/leonardosnt/java-class-tools | ||
*/ | ||
var ConstantType = { | ||
@@ -25,2 +29,3 @@ UTF8: 1, | ||
METHOD_TYPE: 16, | ||
DYNAMIC: 17, | ||
INVOKE_DYNAMIC: 18, | ||
@@ -30,3 +35,3 @@ MODULE: 19, | ||
}; | ||
module.exports = ConstantType; | ||
var _default = ConstantType; | ||
exports["default"] = _default; |
@@ -1,42 +0,61 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _javaClassReader = require('./java-class-reader'); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
Object.defineProperty(exports, "JavaClassFileReader", { | ||
enumerable: true, | ||
get: function get() { | ||
return _javaClassReader["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "JavaClassFileWriter", { | ||
enumerable: true, | ||
get: function get() { | ||
return _javaClassWriter["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "ConstantType", { | ||
enumerable: true, | ||
get: function get() { | ||
return _constantType["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "Opcode", { | ||
enumerable: true, | ||
get: function get() { | ||
return _opcode["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "Modifier", { | ||
enumerable: true, | ||
get: function get() { | ||
return _modifier["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "InstructionParser", { | ||
enumerable: true, | ||
get: function get() { | ||
return _instructionParser.InstructionParser; | ||
} | ||
}); | ||
Object.defineProperty(exports, "Instruction", { | ||
enumerable: true, | ||
get: function get() { | ||
return _instructionParser.Instruction; | ||
} | ||
}); | ||
var _javaClassReader2 = _interopRequireDefault(_javaClassReader); | ||
var _javaClassReader = _interopRequireDefault(require("./java-class-reader")); | ||
var _javaClassWriter = require('./java-class-writer'); | ||
var _javaClassWriter = _interopRequireDefault(require("./java-class-writer")); | ||
var _javaClassWriter2 = _interopRequireDefault(_javaClassWriter); | ||
var _constantType = _interopRequireDefault(require("./constant-type")); | ||
var _constantType = require('./constant-type'); | ||
var _opcode = _interopRequireDefault(require("./opcode")); | ||
var _constantType2 = _interopRequireDefault(_constantType); | ||
var _modifier = _interopRequireDefault(require("./modifier")); | ||
var _opcode = require('./opcode'); | ||
var _instructionParser = require("./instruction-parser"); | ||
var _opcode2 = _interopRequireDefault(_opcode); | ||
var _modifier = require('./modifier'); | ||
var _modifier2 = _interopRequireDefault(_modifier); | ||
var _instructionParser = require('./instruction-parser'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/*! | ||
* https://github.com/leonardosnt/java-class-tools | ||
* | ||
* Copyright (C) 2017 leonardosnt | ||
* Licensed under the MIT License. See LICENSE file in the project root for full license information. | ||
*/ | ||
module.exports = { | ||
JavaClassFileReader: _javaClassReader2.default, | ||
JavaClassFileWriter: _javaClassWriter2.default, | ||
Opcode: _opcode2.default, | ||
ConstantType: _constantType2.default, | ||
Modifier: _modifier2.default, | ||
Instruction: _instructionParser.Instruction, | ||
InstructionParser: _instructionParser.InstructionParser | ||
}; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } |
@@ -1,28 +0,35 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*! | ||
* https://github.com/leonardosnt/java-class-tools | ||
* | ||
* Copyright (C) 2017 leonardosnt | ||
* Licensed under the MIT License. See LICENSE file in the project root for full license information. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.InstructionParser = exports.Instruction = void 0; | ||
var _opcode = require('./opcode'); | ||
var _opcode = _interopRequireDefault(require("./opcode")); | ||
var _opcode2 = _interopRequireDefault(_opcode); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
// -1 = variable length | ||
// index = opcode | ||
var opcodeOperandCount = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, -1, -1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 1, 2, 0, 0, 2, 2, 0, 0, -1, 3, 2, 2, 4, 4, 0]; | ||
var opcodeOperandCount = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, -1, -1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 1, 2, 0, 0, 2, 2, 0, 0, -1, 3, 2, 2, 4, 4, 0]; // index = opcode | ||
// index = opcode | ||
var opcodeMnemonics = ['nop', 'aconst_null', 'iconst_m1', 'iconst_0', 'iconst_1', 'iconst_2', 'iconst_3', 'iconst_4', 'iconst_5', 'lconst_0', 'lconst_1', 'fconst_0', 'fconst_1', 'fconst_2', 'dconst_0', 'dconst_1', 'bipush', 'sipush', 'ldc', 'ldc_w', 'ldc2_w', 'iload', 'lload', 'fload', 'dload', 'aload', 'iload_0', 'iload_1', 'iload_2', 'iload_3', 'lload_0', 'lload_1', 'lload_2', 'lload_3', 'fload_0', 'fload_1', 'fload_2', 'fload_3', 'dload_0', 'dload_1', 'dload_2', 'dload_3', 'aload_0', 'aload_1', 'aload_2', 'aload_3', 'iaload', 'laload', 'faload', 'daload', 'aaload', 'baload', 'caload', 'saload', 'istore', 'lstore', 'fstore', 'dstore', 'astore', 'istore_0', 'istore_1', 'istore_2', 'istore_3', 'lstore_0', 'lstore_1', 'lstore_2', 'lstore_3', 'fstore_0', 'fstore_1', 'fstore_2', 'fstore_3', 'dstore_0', 'dstore_1', 'dstore_2', 'dstore_3', 'astore_0', 'astore_1', 'astore_2', 'astore_3', 'iastore', 'lastore', 'fastore', 'dastore', 'aastore', 'bastore', 'castore', 'sastore', 'pop', 'pop2', 'dup', 'dup_x1', 'dup_x2', 'dup2', 'dup2_x1', 'dup2_x2', 'swap', 'iadd', 'ladd', 'fadd', 'dadd', 'isub', 'lsub', 'fsub', 'dsub', 'imul', 'lmul', 'fmul', 'dmul', 'idiv', 'ldiv', 'fdiv', 'ddiv', 'irem', 'lrem', 'frem', 'drem', 'ineg', 'lneg', 'fneg', 'dneg', 'ishl', 'lshl', 'ishr', 'lshr', 'iushr', 'lushr', 'iand', 'land', 'ior', 'lor', 'ixor', 'lxor', 'iinc', 'i2l', 'i2f', 'i2d', 'l2i', 'l2f', 'l2d', 'f2i', 'f2l', 'f2d', 'd2i', 'd2l', 'd2f', 'i2b', 'i2c', 'i2s', 'lcmp', 'fcmpl', 'fcmpg', 'dcmpl', 'dcmpg', 'ifeq', 'ifne', 'iflt', 'ifge', 'ifgt', 'ifle', 'if_icmpeq', 'if_icmpne', 'if_icmplt', 'if_icmpge', 'if_icmpgt', 'if_icmple', 'if_acmpeq', 'if_acmpne', 'goto', 'jsr', 'ret', 'tableswitch', 'lookupswitch', 'ireturn', 'lreturn', 'freturn', 'dreturn', 'areturn', 'return', 'getstatic', 'putstatic', 'getfield', 'putfield', 'invokevirtual', 'invokespecial', 'invokestatic', 'invokeinterface', 'invokedynamic', 'new', 'newarray', 'anewarray', 'arraylength', 'athrow', 'checkcast', 'instanceof', 'monitorenter', 'monitorexit', 'wide', 'multianewarray', 'ifnull', 'ifnonnull', 'goto_w', 'jsr_w', 'breakpoint']; | ||
var Instruction = function () { | ||
var Instruction = | ||
/*#__PURE__*/ | ||
function () { | ||
function Instruction(opcode, operands, bytecodeOffset) { | ||
@@ -33,3 +40,2 @@ _classCallCheck(this, Instruction); | ||
if (!Array.isArray(operands)) throw TypeError('operands must be an array'); | ||
this.opcode = opcode; | ||
@@ -41,6 +47,6 @@ this.operands = operands; | ||
_createClass(Instruction, [{ | ||
key: 'toString', | ||
key: "toString", | ||
value: function toString() { | ||
var opcodeMnemonic = opcodeMnemonics[this.opcode] || (this.opcode === 0xFE ? 'impdep1' : this.opcode === 0xFF ? 'impdep2' : undefined); | ||
return 'Instruction { opcode: ' + opcodeMnemonic + ', operands: [' + this.operands + '] }'; | ||
return "Instruction { opcode: ".concat(opcodeMnemonic, ", operands: [").concat(this.operands, "] }"); | ||
} | ||
@@ -52,3 +58,7 @@ }]); | ||
var InstructionParser = function () { | ||
exports.Instruction = Instruction; | ||
var InstructionParser = | ||
/*#__PURE__*/ | ||
function () { | ||
function InstructionParser() { | ||
@@ -59,3 +69,3 @@ _classCallCheck(this, InstructionParser); | ||
_createClass(InstructionParser, null, [{ | ||
key: 'toBytecode', | ||
key: "toBytecode", | ||
@@ -67,2 +77,3 @@ /** | ||
* @see {@link https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5} | ||
* @returns {Number[]} | ||
*/ | ||
@@ -75,72 +86,37 @@ value: function toBytecode(instructions) { | ||
var bytecode = []; | ||
var offset = 0; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
while (offset < instructions.length) { | ||
var current = instructions[offset]; | ||
bytecode.push(current.opcode); | ||
try { | ||
for (var _iterator = instructions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var _step$value = _step.value, | ||
opcode = _step$value.opcode, | ||
operands = _step$value.operands; | ||
bytecode.push(opcode); | ||
switch (current.opcode) { | ||
case _opcode2.default.TABLESWITCH: | ||
case _opcode2.default.LOOKUPSWITCH: | ||
{ | ||
var padding = bytecode.length % 4 ? 4 - bytecode.length % 4 : 0; | ||
var operandOffset = 0; | ||
if (opcode === _opcode["default"].TABLESWITCH || opcode === _opcode["default"].LOOKUPSWITCH) { | ||
var padding = bytecode.length % 4 ? 4 - bytecode.length % 4 : 0; | ||
while (padding-- > 0) { | ||
bytecode.push(0); | ||
} | ||
bytecode.push.apply(bytecode, _toConsumableArray(current.operands)); | ||
break; | ||
while (padding-- > 0) { | ||
bytecode.push(0); | ||
} | ||
} // We assume we are given valid operands | ||
case _opcode2.default.WIDE: | ||
{ | ||
var targetOpcode = current.operands[0]; | ||
switch (targetOpcode) { | ||
case _opcode2.default.ILOAD: | ||
case _opcode2.default.FLOAD: | ||
case _opcode2.default.ALOAD: | ||
case _opcode2.default.LLOAD: | ||
case _opcode2.default.DLOAD: | ||
case _opcode2.default.ISTORE: | ||
case _opcode2.default.FSTORE: | ||
case _opcode2.default.ASTORE: | ||
case _opcode2.default.LSTORE: | ||
case _opcode2.default.DSTORE: | ||
case _opcode2.default.RET: | ||
bytecode.push(targetOpcode, current.operands[1], current.operands[2]); | ||
break; | ||
case _opcode2.default.IINC: | ||
bytecode.push(targetOpcode, current.operands[1], current.operands[2], current.operands[3], current.operands[4]); | ||
break; | ||
default: | ||
throw 'Unexpected wide opcode: ' + targetOpcode; | ||
} | ||
break; | ||
} | ||
default: | ||
{ | ||
var operandCount = opcodeOperandCount[current.opcode]; | ||
if (operandCount === undefined) { | ||
throw Error('Unexpected opcode: ' + current); | ||
} | ||
if (current.operands.length > operandCount) { | ||
throw Error('The number of operands in instruction: ' + current + ' is greater than the allowed.'); | ||
} | ||
for (var i = 0; i < operandCount; i++) { | ||
bytecode.push(current.operands[i]); | ||
} | ||
break; | ||
} | ||
bytecode.push.apply(bytecode, _toConsumableArray(operands)); | ||
} | ||
offset++; | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator["return"] != null) { | ||
_iterator["return"](); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
@@ -150,3 +126,2 @@ | ||
} | ||
/** | ||
@@ -157,6 +132,7 @@ * Converts raw bytecode into Instruction objects. | ||
* @see {@link https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5} | ||
* @returns {Instruction[]} | ||
*/ | ||
}, { | ||
key: 'fromBytecode', | ||
key: "fromBytecode", | ||
value: function fromBytecode(bytecode) { | ||
@@ -167,12 +143,13 @@ if (!Array.isArray(bytecode)) { | ||
var parsed = []; | ||
var instructions = []; | ||
var offset = 0; | ||
while (offset < bytecode.length) { | ||
var current = bytecode[offset++]; | ||
var instruction = new Instruction(current, [], offset - 1); | ||
var bytecodeOffset = offset; | ||
var opcode = bytecode[offset++]; | ||
var numOperandBytes = void 0; | ||
switch (current) { | ||
switch (opcode) { | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lookupswitch | ||
case _opcode2.default.LOOKUPSWITCH: | ||
case _opcode["default"].LOOKUPSWITCH: | ||
{ | ||
@@ -182,85 +159,43 @@ var padding = offset % 4 ? 4 - offset % 4 : 0; | ||
// default case bytes + npair bytes | ||
for (var i = 0; i < 8; i++) { | ||
instruction.operands.push(bytecode[offset++]); | ||
} | ||
var npairs = bytecode[offset - 4] << 24 | bytecode[offset - 3] << 16 | bytecode[offset - 2] << 8 | bytecode[offset - 1]; | ||
// match-offset pairs | ||
for (var i = 0; i < npairs * 8; i++) { | ||
instruction.operands.push(bytecode[offset++]); | ||
} | ||
var npairs = bytecode[offset + 4] << 24 | bytecode[offset + 5] << 16 | bytecode[offset + 6] << 8 | bytecode[offset + 7]; | ||
numOperandBytes = 8 + npairs * 8; | ||
break; | ||
} | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch | ||
case _opcode2.default.TABLESWITCH: | ||
case _opcode["default"].TABLESWITCH: | ||
{ | ||
var _padding = offset % 4 ? 4 - offset % 4 : 0; | ||
offset += _padding; // Skip padding | ||
// default bytes (4) + low bytes (4) + high bytes (4) | ||
for (var i = 0; i < 12; i++) { | ||
instruction.operands.push(bytecode[offset++]); | ||
} | ||
var low = bytecode[offset - 8] << 24 | bytecode[offset - 7] << 16 | bytecode[offset - 6] << 8 | bytecode[offset - 5]; | ||
var high = bytecode[offset - 4] << 24 | bytecode[offset - 3] << 16 | bytecode[offset - 2] << 8 | bytecode[offset - 1]; | ||
var low = bytecode[offset + 4] << 24 | bytecode[offset + 5] << 16 | bytecode[offset + 6] << 8 | bytecode[offset + 7]; | ||
var high = bytecode[offset + 8] << 24 | bytecode[offset + 9] << 16 | bytecode[offset + 10] << 8 | bytecode[offset + 11]; | ||
var numJumpOffsets = high - low + 1; | ||
// jump offset's | ||
for (var i = 0; i < numJumpOffsets * 4; i++) { | ||
instruction.operands.push(bytecode[offset++]); | ||
} | ||
numOperandBytes = 3 * 4 + numJumpOffsets * 4; | ||
break; | ||
} | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide | ||
case _opcode2.default.WIDE: | ||
{ | ||
var targetOpcode = bytecode[offset]; | ||
switch (targetOpcode) { | ||
case _opcode2.default.ILOAD: | ||
case _opcode2.default.FLOAD: | ||
case _opcode2.default.ALOAD: | ||
case _opcode2.default.LLOAD: | ||
case _opcode2.default.DLOAD: | ||
case _opcode2.default.ISTORE: | ||
case _opcode2.default.FSTORE: | ||
case _opcode2.default.ASTORE: | ||
case _opcode2.default.LSTORE: | ||
case _opcode2.default.DSTORE: | ||
case _opcode2.default.RET: | ||
instruction.operands.push(bytecode[offset++], bytecode[offset++], bytecode[offset++]); | ||
break; | ||
case _opcode2.default.IINC: | ||
instruction.operands.push(bytecode[offset++], bytecode[offset++], bytecode[offset++], bytecode[offset++], bytecode[offset++]); | ||
break; | ||
case _opcode["default"].WIDE: | ||
numOperandBytes = bytecode[offset] === _opcode["default"].IINC ? 5 : 3; | ||
break; | ||
default: | ||
throw 'Unexpected wide opcode: ' + targetOpcode; | ||
} | ||
break; | ||
} | ||
default: | ||
{ | ||
var operandCount = opcodeOperandCount[current]; | ||
numOperandBytes = opcodeOperandCount[opcode]; | ||
if (operandCount === undefined) { | ||
throw Error('Unexpected opcode: ' + current); | ||
} | ||
if (numOperandBytes === undefined) { | ||
throw Error("Unexpected opcode: ".concat(opcode)); | ||
} | ||
while (operandCount-- > 0) { | ||
instruction.operands.push(bytecode[offset++]); | ||
} | ||
break; | ||
} | ||
break; | ||
} | ||
parsed.push(instruction); | ||
var operands = bytecode.slice(offset, offset + numOperandBytes); | ||
var instruction = new Instruction(opcode, operands, bytecodeOffset); | ||
instructions.push(instruction); | ||
offset += numOperandBytes; | ||
} | ||
return parsed; | ||
return instructions; | ||
} | ||
@@ -272,5 +207,2 @@ }]); | ||
module.exports = { | ||
Instruction: Instruction, | ||
InstructionParser: InstructionParser | ||
}; | ||
exports.InstructionParser = InstructionParser; |
@@ -1,23 +0,21 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*! | ||
* https://github.com/leonardosnt/java-class-tools | ||
* | ||
* Copyright (C) 2017 leonardosnt | ||
* Licensed under the MIT License. See LICENSE file in the project root for full license information. | ||
*/ | ||
var _bytebuffer = _interopRequireDefault(require("bytebuffer")); | ||
var _bytebuffer = require('bytebuffer'); | ||
var _constantType = _interopRequireDefault(require("./constant-type")); | ||
var _bytebuffer2 = _interopRequireDefault(_bytebuffer); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _constantType = require('./constant-type'); | ||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
var _constantType2 = _interopRequireDefault(_constantType); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
@@ -29,3 +27,5 @@ /** | ||
*/ | ||
var JavaClassFileReader = function () { | ||
var JavaClassFileReader = | ||
/*#__PURE__*/ | ||
function () { | ||
function JavaClassFileReader() { | ||
@@ -36,5 +36,4 @@ _classCallCheck(this, JavaClassFileReader); | ||
_createClass(JavaClassFileReader, [{ | ||
key: 'read', | ||
key: "read", | ||
/** | ||
@@ -51,2 +50,3 @@ * Read and parse class file contents. | ||
} | ||
if (typeof source === 'string') { | ||
@@ -56,7 +56,6 @@ return this.readFromFile(source); | ||
this.buf = _bytebuffer2.default.wrap(source); | ||
this.classFile = new function ClassFile() {}(); | ||
this.buf = _bytebuffer["default"].wrap(source); | ||
this.classFile = new function ClassFile() {}(); // Read magic | ||
// Read magic | ||
if (this.buf.readUInt8() !== 0xCA || this.buf.readUInt8() !== 0xFE || this.buf.readUInt8() !== 0xBA || this.buf.readUInt8() !== 0xBE) { | ||
if (this.buf.readUint32() !== 0xCAFEBABE) { | ||
throw Error('Invalid MAGIC value'); | ||
@@ -67,44 +66,34 @@ } | ||
this.classFile.major_version = this.buf.readUint16(); | ||
this.classFile.constant_pool_count = this.buf.readUint16(); | ||
this.classFile.constant_pool = this._readConstantPool(this.classFile.constant_pool_count - 1); | ||
this.classFile.access_flags = this.buf.readUint16(); | ||
this.classFile.this_class = this.buf.readUint16(); | ||
this.classFile.super_class = this.buf.readUint16(); | ||
this.classFile.interfaces_count = this.buf.readUint16(); | ||
this.classFile.interfaces = this._readInterfaces(this.classFile.interfaces_count); | ||
this.classFile.fields_count = this.buf.readUint16(); | ||
this.classFile.fields = this._readCommonFieldMethodArray(this.classFile.fields_count); | ||
this.classFile.fields = this._readMemberInfoArray(this.classFile.fields_count); | ||
this.classFile.methods_count = this.buf.readUint16(); | ||
this.classFile.methods = this._readCommonFieldMethodArray(this.classFile.methods_count); | ||
this.classFile.methods = this._readMemberInfoArray(this.classFile.methods_count); | ||
this.classFile.attributes_count = this.buf.readUint16(); | ||
this.classFile.attributes = this._readAttributeInfoArray(this.classFile.attributes_count); | ||
var classFile = this.classFile; // Dispose | ||
var classFile = this.classFile; | ||
// Dispose | ||
delete this.buf; | ||
delete this.classFile; | ||
return classFile; | ||
} | ||
}, { | ||
key: 'readFromFile', | ||
key: "readFromFile", | ||
value: function readFromFile(path) { | ||
if ((typeof process === 'undefined' ? 'undefined' : _typeof(process)) !== undefined) { | ||
// node | ||
if ((typeof process === "undefined" ? "undefined" : _typeof(process)) !== undefined) { | ||
var fs = require('fs'); | ||
return this.read(fs.readFileSync(path)); | ||
} else { | ||
throw Error('not supported in browser.'); | ||
throw Error('readFromFile is not supported in the browser.'); | ||
} | ||
} | ||
/** | ||
* The "method_info" and "field_info" structures are identical. | ||
* Read an array of field_info or method_info structures. | ||
* | ||
@@ -116,28 +105,30 @@ * https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6 | ||
}, { | ||
key: '_readCommonFieldMethodArray', | ||
value: function _readCommonFieldMethodArray(count) { | ||
var values = []; | ||
while (count-- > 0) { | ||
var struct = { | ||
key: "_readMemberInfoArray", | ||
value: function _readMemberInfoArray(count) { | ||
var members = new Array(count); | ||
for (var i = 0; i < count; i++) { | ||
var memberInfo = { | ||
access_flags: this.buf.readUint16(), | ||
name_index: this.buf.readUint16(), | ||
descriptor_index: this.buf.readUint16(), | ||
attributes_count: this.buf.readUint16(), | ||
attributes: [] | ||
attributes_count: this.buf.readUint16() | ||
}; | ||
struct.attributes = this._readAttributeInfoArray(struct.attributes_count); | ||
values.push(struct); | ||
memberInfo.attributes = this._readAttributeInfoArray(memberInfo.attributes_count); | ||
members[i] = memberInfo; | ||
} | ||
return values; | ||
return members; | ||
} | ||
}, { | ||
key: '_readAttributeInfoArray', | ||
key: "_readAttributeInfoArray", | ||
value: function _readAttributeInfoArray(attributes_count) { | ||
var attributes = []; | ||
while (attributes_count-- > 0) { | ||
attributes.push(this._readAttributeInfo()); | ||
var attributes = new Array(attributes_count); | ||
for (var i = 0; i < attributes_count; i++) { | ||
attributes[i] = this._readAttributeInfo(); | ||
} | ||
return attributes; | ||
} | ||
/** | ||
@@ -149,3 +140,3 @@ * Reads the "verification_type_info" structure. | ||
}, { | ||
key: '_readVerificationTypeInfo', | ||
key: "_readVerificationTypeInfo", | ||
value: function _readVerificationTypeInfo() { | ||
@@ -155,2 +146,3 @@ var type_info = { | ||
}; | ||
if (type_info.tag === 7) { | ||
@@ -161,5 +153,5 @@ type_info.cpool_index = this.buf.readUint16(); | ||
} | ||
return type_info; | ||
} | ||
/** | ||
@@ -171,3 +163,3 @@ * Reads the "type_annotation" structure | ||
}, { | ||
key: '_readTypeAnnotation', | ||
key: "_readTypeAnnotation", | ||
value: function _readTypeAnnotation() { | ||
@@ -177,46 +169,49 @@ var type_annotation = { | ||
target_info: {} | ||
}; | ||
}; // Reads the "target_info" union. | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.20-400 | ||
// Reads the "target_info" union. | ||
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.20-400 | ||
switch (type_annotation.target_type) { | ||
// type_parameter_target | ||
case 0x00:case 0x01: | ||
case 0x00: | ||
case 0x01: | ||
type_annotation.target_info.type_parameter_index = this.buf.readUint8(); | ||
break; | ||
// supertype_target | ||
// supertype_target | ||
case 0x10: | ||
type_annotation.target_info.supertype_index = this.buf.readUint16(); | ||
break; | ||
// type_parameter_bound_target | ||
// type_parameter_bound_target | ||
case 0x11:case 0x12: | ||
case 0x11: | ||
case 0x12: | ||
type_annotation.target_info.type_parameter_index = this.buf.readUint8(); | ||
type_annotation.target_info.bound_index = this.buf.readUint8(); | ||
break; | ||
// empty_target | ||
// empty_target | ||
case 0x13:case 0x14:case 0x15: | ||
case 0x13: | ||
case 0x14: | ||
case 0x15: | ||
// empty | ||
break; | ||
// formal_parameter_target | ||
// formal_parameter_target | ||
case 0x16: | ||
type_annotation.target_info.formal_parameter_index = this.buf.readUint8(); | ||
break; | ||
// throws_target | ||
// throws_target | ||
case 0x17: | ||
type_annotation.target_info.throws_type_index = this.buf.readUint16(); | ||
break; | ||
// localvar_target | ||
// localvar_target | ||
case 0x40:case 0x41: | ||
case 0x40: | ||
case 0x41: | ||
{ | ||
type_annotation.target_info.table_length = this.buf.readUint16(); | ||
type_annotation.target_info.table = []; | ||
type_annotation.target_info.table = new Array(type_annotation.target_info.table_length); | ||
var table_length = type_annotation.target_info.table_length; | ||
while (table_length-- > 0) { | ||
for (var i = 0; i < type_annotation.target_info.table_length; i++) { | ||
var table_entry = { | ||
@@ -227,19 +222,27 @@ start_pc: this.buf.readUint16(), | ||
}; | ||
type_annotation.target_info.table.push(table_entry); | ||
type_annotation.target_info.table[i] = table_entry; | ||
} | ||
break; | ||
} | ||
// catch_target | ||
// catch_target | ||
case 0x42: | ||
type_annotation.target_info.exception_table_index = this.buf.readUint16(); | ||
break; | ||
// offset_target | ||
// offset_target | ||
case 0x43:case 0x44:case 0x45:case 0x46: | ||
case 0x43: | ||
case 0x44: | ||
case 0x45: | ||
case 0x46: | ||
type_annotation.target_info.offset = this.buf.readUint16(); | ||
break; | ||
// type_argument_target | ||
// type_argument_target | ||
case 0x47:case 0x48:case 0x49:case 0x4A:case 0x4B: | ||
case 0x47: | ||
case 0x48: | ||
case 0x49: | ||
case 0x4A: | ||
case 0x4B: | ||
type_annotation.target_info.offset = this.buf.readUint16(); | ||
@@ -250,18 +253,16 @@ type_annotation.target_info.type_argument_index = this.buf.readUint8(); | ||
default: | ||
throw Error('Unexpected target_type: ' + type_annotation.target_type); | ||
} | ||
throw Error("Unexpected target_type: ".concat(type_annotation.target_type)); | ||
} // Reads "type_path" structure | ||
// Reads "type_path" structure | ||
type_annotation.type_path = { | ||
path_length: this.buf.readUint8(), | ||
path: [] | ||
path_length: this.buf.readUint8() | ||
}; | ||
type_annotation.type_path.path = new Array(type_annotation.type_path.path_length); | ||
var path_length = type_annotation.type_path.path_length; | ||
while (path_length-- > 0) { | ||
var path_entry = { | ||
for (var _i = 0; _i < type_annotation.type_path.path_length; _i++) { | ||
type_annotation.type_path.path[_i] = { | ||
type_path_kind: this.buf.readUint8(), | ||
type_argument_index: this.buf.readUint8() | ||
}; | ||
type_annotation.type_path.path.push(path_entry); | ||
} | ||
@@ -271,15 +272,13 @@ | ||
type_annotation.num_element_value_pairs = this.buf.readUint16(); | ||
type_annotation.element_value_pairs = []; | ||
type_annotation.element_value_pairs = new Array(type_annotation.num_element_value_pairs); | ||
var num_element_value_pairs = type_annotation.num_element_value_pairs; | ||
while (num_element_value_pairs-- > 0) { | ||
var element_value_entry = { | ||
for (var _i2 = 0; _i2 < type_annotation.num_element_value_pairs; _i2++) { | ||
type_annotation.element_value_pairs[_i2] = { | ||
element_name_index: this.buf.readUint16(), | ||
element_value: this._readElementValue() | ||
}; | ||
type_annotation.element_value_pairs.push(element_value_entry); | ||
} | ||
return type_annotation; | ||
} | ||
/** | ||
@@ -291,3 +290,3 @@ * Reads the "attribute_info" structure | ||
}, { | ||
key: '_readAttributeInfo', | ||
key: "_readAttributeInfo", | ||
value: function _readAttributeInfo() { | ||
@@ -298,3 +297,2 @@ var attribute = { | ||
}; | ||
var attributeNameBytes = this.classFile.constant_pool[attribute.attribute_name_index].bytes; | ||
@@ -304,2 +302,6 @@ var attributeName = String.fromCharCode.apply(null, attributeNameBytes); // TODO: is this safe? | ||
switch (attributeName) { | ||
case 'Deprecated': | ||
case 'Synthetic': | ||
break; | ||
case 'RuntimeInvisibleAnnotations': | ||
@@ -309,23 +311,18 @@ case 'RuntimeVisibleAnnotations': | ||
attribute.num_annotations = this.buf.readUint16(); | ||
attribute.annotations = []; | ||
var num_annotations = attribute.num_annotations; | ||
while (num_annotations-- > 0) { | ||
attribute.annotations.push(this._readAttributeAnnotation()); | ||
attribute.annotations = new Array(attribute.num_annotations); | ||
for (var i = 0; i < attribute.num_annotations; i++) { | ||
attribute.annotations[i] = this._readAttributeAnnotation(); | ||
} | ||
break; | ||
} | ||
// There's no additional information | ||
case 'Deprecated': | ||
case 'Synthetic': | ||
break; | ||
case 'InnerClasses': | ||
{ | ||
attribute.number_of_classes = this.buf.readUint16(); | ||
attribute.classes = []; | ||
attribute.classes = new Array(attribute.number_of_classes); | ||
var number_of_classes = attribute.number_of_classes; | ||
while (number_of_classes-- > 0) { | ||
var inner_class = { | ||
for (var _i3 = 0; _i3 < attribute.number_of_classes; _i3++) { | ||
attribute.classes[_i3] = { | ||
inner_class_info_index: this.buf.readUint16(), | ||
@@ -336,4 +333,4 @@ outer_class_info_index: this.buf.readUint16(), | ||
}; | ||
attribute.classes.push(inner_class); | ||
} | ||
break; | ||
@@ -345,7 +342,6 @@ } | ||
attribute.local_variable_table_length = this.buf.readUint16(); | ||
attribute.local_variable_table = []; | ||
attribute.local_variable_table = new Array(attribute.local_variable_table_length); | ||
var local_variable_table_length = attribute.local_variable_table_length; | ||
while (local_variable_table_length-- > 0) { | ||
var local_variable = { | ||
for (var _i4 = 0; _i4 < attribute.local_variable_table_length; _i4++) { | ||
attribute.local_variable_table[_i4] = { | ||
start_pc: this.buf.readUint16(), | ||
@@ -357,4 +353,4 @@ length: this.buf.readUint16(), | ||
}; | ||
attribute.local_variable_table.push(local_variable); | ||
} | ||
break; | ||
@@ -366,7 +362,6 @@ } | ||
attribute.local_variable_type_table_length = this.buf.readUint16(); | ||
attribute.local_variable_type_table = []; | ||
attribute.local_variable_type_table = new Array(attribute.local_variable_type_table_length); | ||
var local_variable_type_table_length = attribute.local_variable_type_table_length; | ||
while (local_variable_type_table_length-- > 0) { | ||
var local_variable_type = { | ||
for (var _i5 = 0; _i5 < attribute.local_variable_type_table_length; _i5++) { | ||
attribute.local_variable_type_table[_i5] = { | ||
start_pc: this.buf.readUint16(), | ||
@@ -378,4 +373,4 @@ length: this.buf.readUint16(), | ||
}; | ||
attribute.local_variable_type_table.push(local_variable_type); | ||
} | ||
break; | ||
@@ -388,17 +383,17 @@ } | ||
attribute.num_parameters = this.buf.readUint8(); | ||
attribute.parameter_annotations = []; | ||
attribute.parameter_annotations = new Array(attribute.num_parameters); | ||
var num_parameters = attribute.num_parameters; | ||
while (num_parameters-- > 0) { | ||
for (var parameterIndex = 0; parameterIndex < attribute.num_parameters; parameterIndex++) { | ||
var parameter_annotation = { | ||
num_annotations: this.buf.readUint16(), | ||
annotations: [] | ||
num_annotations: this.buf.readUint16() | ||
}; | ||
parameter_annotation.annotations = new Array(parameter_annotation.num_annotations); | ||
var _num_annotations = parameter_annotation.num_annotations; | ||
while (_num_annotations-- > 0) { | ||
parameter_annotation.annotations.push(this._readAttributeAnnotation()); | ||
for (var annotationIndex = 0; annotationIndex < parameter_annotation.num_annotations; annotationIndex++) { | ||
parameter_annotation.annotations[annotationIndex] = this._readAttributeAnnotation(); | ||
} | ||
attribute.parameter_annotations.push(parameter_annotation); | ||
attribute.parameter_annotations[parameterIndex] = parameter_annotation; | ||
} | ||
break; | ||
@@ -410,18 +405,18 @@ } | ||
attribute.num_bootstrap_methods = this.buf.readUint16(); | ||
attribute.bootstrap_methods = []; | ||
attribute.bootstrap_methods = new Array(attribute.num_bootstrap_methods); | ||
var num_bootstrap_methods = attribute.num_bootstrap_methods; | ||
while (num_bootstrap_methods-- > 0) { | ||
for (var bootstrapMethodIndex = 0; bootstrapMethodIndex < attribute.num_bootstrap_methods; bootstrapMethodIndex++) { | ||
var bootstrap_method = { | ||
bootstrap_method_ref: this.buf.readUint16(), | ||
num_bootstrap_arguments: this.buf.readUint16(), | ||
bootstrap_arguments: [] | ||
num_bootstrap_arguments: this.buf.readUint16() | ||
}; | ||
bootstrap_method.bootstrap_arguments = new Array(bootstrap_method.num_bootstrap_arguments); | ||
var num_bootstrap_arguments = bootstrap_method.num_bootstrap_arguments; | ||
while (num_bootstrap_arguments-- > 0) { | ||
bootstrap_method.bootstrap_arguments.push(this.buf.readUint16()); | ||
for (var bootstrapArgumentIndex = 0; bootstrapArgumentIndex < bootstrap_method.num_bootstrap_arguments; bootstrapArgumentIndex++) { | ||
bootstrap_method.bootstrap_arguments[bootstrapArgumentIndex] = this.buf.readUint16(); | ||
} | ||
attribute.bootstrap_methods.push(bootstrap_method); | ||
attribute.bootstrap_methods[bootstrapMethodIndex] = bootstrap_method; | ||
} | ||
break; | ||
@@ -434,8 +429,8 @@ } | ||
attribute.num_annotations = this.buf.readUint16(); | ||
attribute.annotations = []; | ||
attribute.annotations = new Array(attribute.num_annotations); | ||
var _num_annotations2 = attribute.num_annotations; | ||
while (_num_annotations2-- > 0) { | ||
attribute.annotations.push(this._readTypeAnnotation()); | ||
for (var _i6 = 0; _i6 < attribute.num_annotations; _i6++) { | ||
attribute.annotations[_i6] = this._readTypeAnnotation(); | ||
} | ||
break; | ||
@@ -446,8 +441,8 @@ } | ||
{ | ||
attribute.debug_extension = []; | ||
attribute.debug_extension = new Array(attribute.attribute_length); | ||
var attribute_length = attribute.attribute_length; | ||
while (attribute_length-- > 0) { | ||
attribute.debug_extension.push(this.buf.readUint8()); | ||
for (var _i7 = 0; _i7 < attribute.attribute_length; _i7++) { | ||
attribute.debug_extension[_i7] = this.buf.readUint8(); | ||
} | ||
break; | ||
@@ -471,25 +466,12 @@ } | ||
{ | ||
attribute.parameters_count = this.buf.readUInt8(); | ||
attribute.parameters = []; | ||
attribute.parameters_count = this.buf.readUint8(); | ||
attribute.parameters = new Array(attribute.parameters_count); | ||
var parameters_count = attribute.parameters_count; | ||
while (parameters_count-- > 0) { | ||
var parameter = { | ||
for (var _i8 = 0; _i8 < attribute.parameters_count; _i8++) { | ||
attribute.parameters[_i8] = { | ||
name_index: this.buf.readUint16(), | ||
access_flags: this.buf.readUint16() | ||
}; | ||
attribute.parameters.push(parameter); | ||
} | ||
break; | ||
} | ||
case 'Exceptions': | ||
{ | ||
attribute.number_of_exceptions = this.buf.readUint16(); | ||
attribute.exception_index_table = []; | ||
var number_of_exceptions = attribute.number_of_exceptions; | ||
while (number_of_exceptions-- > 0) { | ||
attribute.exception_index_table.push(this.buf.readUint16()); | ||
} | ||
break; | ||
@@ -506,313 +488,315 @@ } | ||
/** | ||
* http://download.oracle.com/otndocs/jcp/7247-j2me_cldc-1.1-fr-spec-oth-JSpec/ | ||
* | ||
* Appendix1-verifier.pdf at "2.1 Stack map format" | ||
* | ||
* "According to the CLDC specification, the sizes of some fields are not 16bit | ||
* but 32bit if the code size is more than 64K or the number of the local variables | ||
* is more than 64K. However, for the J2ME CLDC technology, they are always 16bit. | ||
* The implementation of the StackMap class assumes they are 16bit." - javaassist | ||
*/ | ||
case 'StackMap': | ||
{ | ||
attribute.number_of_entries = this.buf.readUint16(); | ||
attribute.entries = []; | ||
return this._readStackMapAttribute(attribute); | ||
var number_of_entries = attribute.number_of_entries; | ||
while (number_of_entries-- > 0) { | ||
var stack_map_frame = { | ||
offset: this.buf.readUint16(), | ||
number_of_locals: this.buf.readUint16(), | ||
locals: [], | ||
stack: [] | ||
}; | ||
case 'Exceptions': | ||
return this._readExceptionsAttribute(attribute); | ||
var number_of_locals = stack_map_frame.number_of_locals; | ||
while (number_of_locals-- > 0) { | ||
stack_map_frame.locals.push(this._readVerificationTypeInfo()); | ||
} | ||
case 'StackMapTable': | ||
return this._readStackMapTableAttribute(attribute); | ||
stack_map_frame.number_of_stack_items = this.buf.readUInt16(); | ||
case 'Code': | ||
return this._readCodeAttribute(attribute); | ||
var number_of_stack_items = stack_map_frame.number_of_stack_items; | ||
while (number_of_stack_items-- > 0) { | ||
stack_map_frame.stack.push(this._readVerificationTypeInfo()); | ||
} | ||
case 'LineNumberTable': | ||
return this._readLineNumberTableAttribute(attribute); | ||
attribute.entries.push(stack_map_frame); | ||
} | ||
break; | ||
case 'Module': | ||
return this._readModuleAttribute(attribute); | ||
case 'ModulePackages': | ||
return this._readModulePackagesAttribute(attribute); | ||
case 'ModuleMainClass': | ||
attribute.main_class_index = this.buf.readUint16(); | ||
break; | ||
case 'NestHost': | ||
attribute.host_class_index = this.buf.readUint16(); | ||
break; | ||
case 'NestMembers': | ||
attribute.number_of_classes = this.buf.readUint16(); | ||
attribute.classes = new Array(attribute.number_of_classes); | ||
for (var _i9 = 0; _i9 < attribute.number_of_classes; _i9++) { | ||
attribute.classes[_i9] = this.buf.readUint16(); | ||
} | ||
case 'StackMapTable': | ||
break; | ||
// Unknown attributes | ||
// See: https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.1 | ||
default: | ||
{ | ||
attribute.number_of_entries = this.buf.readUint16(); | ||
attribute.entries = []; | ||
attribute.info = new Array(attribute.attribute_length); | ||
var _number_of_entries = attribute.number_of_entries; | ||
while (_number_of_entries-- > 0) { | ||
var _stack_map_frame = { | ||
frame_type: this.buf.readUint8() | ||
}; | ||
for (var _i10 = 0; _i10 < attribute.attribute_length; _i10++) { | ||
attribute.info[_i10] = this.buf.readUint8(); | ||
} | ||
} | ||
} | ||
// Shorthand | ||
var frame_type = _stack_map_frame.frame_type; | ||
return attribute; | ||
} | ||
}, { | ||
key: "_readCodeAttribute", | ||
value: function _readCodeAttribute(attribute) { | ||
attribute.max_stack = this.buf.readUint16(); | ||
attribute.max_locals = this.buf.readUint16(); | ||
attribute.code_length = this.buf.readUint32(); | ||
attribute.code = new Array(attribute.code_length); // Reads "code" array | ||
/** | ||
* offset_delta's that is "constant" are omited. | ||
* | ||
* like in "SAME" that offset_delta is the value of the tag item, frame_type. Or in | ||
* "SAME_LOCALS_1_STACK_ITEM" that offset_delta is given by the formula frame_type - 64. | ||
* | ||
* "SAME (0-63)" frame_type is omited because it's empty. | ||
* | ||
* See https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4 | ||
* for more information. | ||
*/ | ||
for (var i = 0; i < attribute.code_length; i++) { | ||
attribute.code[i] = this.buf.readUint8(); | ||
} | ||
// SAME_LOCALS_1_STACK_ITEM | ||
if (frame_type >= 64 && frame_type <= 127) { | ||
_stack_map_frame.stack = [this._readVerificationTypeInfo()]; | ||
} | ||
// SAME_LOCALS_1_STACK_ITEM_EXTENDED | ||
else if (_stack_map_frame.frame_type === 247) { | ||
_stack_map_frame.offset_delta = this.buf.readUint16(); | ||
_stack_map_frame.stack = [this._readVerificationTypeInfo()]; | ||
} | ||
// CHOP = 248-250, SAME_FRAME_EXTENDED = 251 | ||
else if (frame_type >= 248 && frame_type <= 251) { | ||
_stack_map_frame.offset_delta = this.buf.readUint16(); | ||
} | ||
// APPEND | ||
else if (frame_type >= 252 && frame_type <= 254) { | ||
_stack_map_frame.offset_delta = this.buf.readUint16(); | ||
_stack_map_frame.locals = []; | ||
attribute.exception_table_length = this.buf.readUint16(); | ||
attribute.exception_table = new Array(attribute.exception_table_length); // Reads exception_table | ||
var _number_of_locals = frame_type - 251; | ||
while (_number_of_locals-- > 0) { | ||
_stack_map_frame.locals.push(this._readVerificationTypeInfo()); | ||
} | ||
} | ||
// FULL_FRAME | ||
else if (frame_type === 255) { | ||
_stack_map_frame.offset_delta = this.buf.readUint16(); | ||
_stack_map_frame.number_of_locals = this.buf.readUint16(); | ||
_stack_map_frame.locals = []; | ||
for (var _i11 = 0; _i11 < attribute.exception_table_length; _i11++) { | ||
attribute.exception_table[_i11] = { | ||
start_pc: this.buf.readUint16(), | ||
end_pc: this.buf.readUint16(), | ||
handler_pc: this.buf.readUint16(), | ||
catch_type: this.buf.readUint16() | ||
}; | ||
} | ||
var _number_of_locals2 = _stack_map_frame.number_of_locals; | ||
while (_number_of_locals2-- > 0) { | ||
_stack_map_frame.locals.push(this._readVerificationTypeInfo()); | ||
} | ||
attribute.attributes_count = this.buf.readUint16(); | ||
attribute.attributes = this._readAttributeInfoArray(attribute.attributes_count); | ||
return attribute; | ||
} | ||
}, { | ||
key: "_readLineNumberTableAttribute", | ||
value: function _readLineNumberTableAttribute(attribute) { | ||
attribute.line_number_table_length = this.buf.readUint16(); | ||
attribute.line_number_table = new Array(attribute.line_number_table_length); | ||
_stack_map_frame.number_of_stack_items = this.buf.readUint16(); | ||
_stack_map_frame.stack = []; | ||
for (var i = 0; i < attribute.line_number_table_length; i++) { | ||
attribute.line_number_table[i] = { | ||
start_pc: this.buf.readUint16(), | ||
line_number: this.buf.readUint16() | ||
}; | ||
} | ||
var _number_of_stack_items = _stack_map_frame.number_of_stack_items; | ||
while (_number_of_stack_items-- > 0) { | ||
_stack_map_frame.stack.push(this._readVerificationTypeInfo()); | ||
} | ||
} | ||
attribute.entries.push(_stack_map_frame); | ||
} | ||
break; | ||
} | ||
return attribute; | ||
} // TODO: this function is being deoptimized one time... Check why | ||
case 'Code': | ||
{ | ||
attribute.max_stack = this.buf.readUint16(); | ||
attribute.max_locals = this.buf.readUint16(); | ||
attribute.code_length = this.buf.readUint32(); | ||
attribute.code = []; | ||
}, { | ||
key: "_readStackMapTableAttribute", | ||
value: function _readStackMapTableAttribute(attribute) { | ||
attribute.number_of_entries = this.buf.readUint16(); | ||
attribute.entries = new Array(attribute.number_of_entries); | ||
// Reads "code" array | ||
var code_length = attribute.code_length; | ||
while (code_length-- > 0) { | ||
attribute.code.push(this.buf.readUint8()); | ||
} | ||
for (var entryIndex = 0; entryIndex < attribute.number_of_entries; entryIndex++) { | ||
var stack_map_frame = { | ||
frame_type: this.buf.readUint8() | ||
}; // Shorthand | ||
attribute.exception_table_length = this.buf.readUint16(); | ||
attribute.exception_table = []; | ||
var frame_type = stack_map_frame.frame_type; | ||
/** | ||
* offset_delta's that are "constant" are omitted. | ||
* E.g: | ||
* The offset_delta for the "same_frame" is the value of the tag item (frame_type). | ||
* The offset_delta for the "same_locals_1_stack_item_frame " is given by the formula frame_type - 64. | ||
* | ||
* See https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4 | ||
* for more information. | ||
*/ | ||
// SAME | ||
// Reads exception_table | ||
var exception_table_length = attribute.exception_table_length; | ||
while (exception_table_length-- > 0) { | ||
var exception_entry = { | ||
start_pc: this.buf.readUint16(), | ||
end_pc: this.buf.readUint16(), | ||
handler_pc: this.buf.readUint16(), | ||
catch_type: this.buf.readUint16() | ||
}; | ||
attribute.exception_table.push(exception_entry); | ||
} | ||
if (frame_type >= 0 && frame_type <= 63) { | ||
attribute.entries[entryIndex] = stack_map_frame; | ||
continue; | ||
} // SAME_LOCALS_1_STACK_ITEM | ||
attribute.attributes_count = this.buf.readUint16(); | ||
attribute.attributes = this._readAttributeInfoArray(attribute.attributes_count); | ||
break; | ||
} | ||
case 'LineNumberTable': | ||
{ | ||
attribute.line_number_table_length = this.buf.readUint16(); | ||
attribute.line_number_table = []; | ||
if (frame_type >= 64 && frame_type <= 127) { | ||
stack_map_frame.stack = [this._readVerificationTypeInfo()]; | ||
} // SAME_LOCALS_1_STACK_ITEM_EXTENDED | ||
else if (stack_map_frame.frame_type === 247) { | ||
stack_map_frame.offset_delta = this.buf.readUint16(); | ||
stack_map_frame.stack = [this._readVerificationTypeInfo()]; | ||
} // CHOP = 248-250, SAME_FRAME_EXTENDED = 251 | ||
else if (frame_type >= 248 && frame_type <= 251) { | ||
stack_map_frame.offset_delta = this.buf.readUint16(); | ||
} // APPEND | ||
else if (frame_type >= 252 && frame_type <= 254) { | ||
var numberOfLocals = frame_type - 251; | ||
stack_map_frame.offset_delta = this.buf.readUint16(); | ||
stack_map_frame.locals = new Array(numberOfLocals); | ||
var line_number_table_length = attribute.line_number_table_length; | ||
while (line_number_table_length-- > 0) { | ||
var line_number = { | ||
start_pc: this.buf.readUint16(), | ||
line_number: this.buf.readUint16() | ||
}; | ||
attribute.line_number_table.push(line_number); | ||
} | ||
break; | ||
} | ||
for (var i = 0; i < numberOfLocals; i++) { | ||
stack_map_frame.locals[i] = this._readVerificationTypeInfo(); | ||
} | ||
} // FULL_FRAME | ||
else if (frame_type === 255) { | ||
stack_map_frame.offset_delta = this.buf.readUint16(); | ||
stack_map_frame.number_of_locals = this.buf.readUint16(); | ||
stack_map_frame.locals = new Array(stack_map_frame.number_of_locals); | ||
case 'ModuleMainClass': | ||
attribute.main_class_index = this.buf.readUint16(); | ||
break; | ||
for (var _i12 = 0; _i12 < stack_map_frame.number_of_locals; _i12++) { | ||
stack_map_frame.locals[_i12] = this._readVerificationTypeInfo(); | ||
} | ||
case 'Module': | ||
{ | ||
attribute.module_name_index = this.buf.readUint16(); | ||
attribute.module_flags = this.buf.readUint16(); | ||
attribute.module_version_index = this.buf.readUint16(); | ||
stack_map_frame.number_of_stack_items = this.buf.readUint16(); | ||
stack_map_frame.stack = new Array(stack_map_frame.number_of_stack_items); | ||
attribute.requires_count = this.buf.readUint16(); | ||
attribute.requires = []; | ||
for (var _i13 = 0; _i13 < stack_map_frame.number_of_stack_items; _i13++) { | ||
stack_map_frame.stack[_i13] = this._readVerificationTypeInfo(); | ||
} | ||
} | ||
var requires_count = attribute.requires_count; | ||
while (requires_count-- > 0) { | ||
attribute.requires.push({ | ||
requires_index: this.buf.readUint16(), | ||
requires_flags: this.buf.readUint16(), | ||
requires_version_index: this.buf.readUint16() | ||
}); | ||
} | ||
attribute.entries[entryIndex] = stack_map_frame; | ||
} | ||
attribute.exports_count = this.buf.readUint16(); | ||
attribute.exports = []; | ||
return attribute; | ||
} | ||
}, { | ||
key: "_readExceptionsAttribute", | ||
value: function _readExceptionsAttribute(attribute) { | ||
attribute.number_of_exceptions = this.buf.readUint16(); | ||
attribute.exception_index_table = new Array(attribute.number_of_exceptions); | ||
var exports_count = attribute.exports_count; | ||
while (exports_count-- > 0) { | ||
var entry = { | ||
exports_index: this.buf.readUint16(), | ||
exports_flags: this.buf.readUint16(), | ||
exports_to_count: this.buf.readUint16(), | ||
exports_to_index: [] | ||
}; | ||
for (var i = 0; i < attribute.number_of_exceptions; i++) { | ||
attribute.exception_index_table[i] = this.buf.readUint16(); | ||
} | ||
var exports_to_count = entry.exports_to_count; | ||
while (exports_to_count-- > 0) { | ||
entry.exports_to_index.push(this.buf.readUint16()); | ||
} | ||
return attribute; | ||
} | ||
/** | ||
* http://download.oracle.com/otndocs/jcp/7247-j2me_cldc-1.1-fr-spec-oth-JSpec/ | ||
* | ||
* Appendix1-verifier.pdf at "2.1 Stack map format" | ||
* | ||
* "According to the CLDC specification, the sizes of some fields are not 16bit | ||
* but 32bit if the code size is more than 64K or the number of the local variables | ||
* is more than 64K. However, for the J2ME CLDC technology, they are always 16bit. | ||
* The implementation of the StackMap class assumes they are 16bit." - javaassist | ||
*/ | ||
attribute.exports.push(entry); | ||
} | ||
}, { | ||
key: "_readStackMapAttribute", | ||
value: function _readStackMapAttribute(attribute) { | ||
attribute.number_of_entries = this.buf.readUint16(); | ||
attribute.entries = new Array(attribute.number_of_entries); | ||
attribute.opens_count = this.buf.readUint16(); | ||
attribute.opens = []; | ||
for (var entryIndex = 0; entryIndex < attribute.number_of_entries; entryIndex++) { | ||
var stack_map_frame = { | ||
offset: this.buf.readUint16() | ||
}; // Read locals | ||
var opens_count = attribute.opens_count; | ||
while (opens_count-- > 0) { | ||
var _entry = { | ||
opens_index: this.buf.readUint16(), | ||
opens_flags: this.buf.readUint16(), | ||
opens_to_count: this.buf.readUint16(), | ||
opens_to_index: [] | ||
}; | ||
stack_map_frame.number_of_locals = this.buf.readUint16(); | ||
stack_map_frame.locals = new Array(stack_map_frame.number_of_locals); | ||
var opens_to_count = _entry.opens_to_count; | ||
while (opens_to_count-- > 0) { | ||
_entry.opens_to_index.push(this.buf.readUint16()); | ||
} | ||
for (var i = 0; i < stack_map_frame.number_of_locals; i++) { | ||
stack_map_frame.locals[i] = this._readVerificationTypeInfo(); | ||
} // Read stack | ||
attribute.opens.push(_entry); | ||
} | ||
attribute.uses_count = this.buf.readUint16(); | ||
attribute.uses_index = []; | ||
stack_map_frame.number_of_stack_items = this.buf.readUint16(); | ||
stack_map_frame.stack = new Array(stack_map_frame.number_of_stack_items); | ||
var uses_count = attribute.uses_count; | ||
while (uses_count-- > 0) { | ||
attribute.uses_index.push(this.buf.readUint16()); | ||
} | ||
for (var _i14 = 0; _i14 < stack_map_frame.number_of_stack_items; _i14++) { | ||
stack_map_frame.stack[_i14] = this._readVerificationTypeInfo(); | ||
} | ||
attribute.provides_count = this.buf.readUint16(); | ||
attribute.provides = []; | ||
attribute.entries[entryIndex] = stack_map_frame; | ||
} | ||
var provides_count = attribute.provides_count; | ||
while (provides_count-- > 0) { | ||
var _entry2 = { | ||
provides_index: this.buf.readUint16(), | ||
provides_with_count: this.buf.readUint16(), | ||
provides_with_index: [] | ||
}; | ||
return attribute; | ||
} | ||
}, { | ||
key: "_readModuleAttribute", | ||
value: function _readModuleAttribute(attribute) { | ||
attribute.module_name_index = this.buf.readUint16(); | ||
attribute.module_flags = this.buf.readUint16(); | ||
attribute.module_version_index = this.buf.readUint16(); | ||
attribute.requires_count = this.buf.readUint16(); | ||
attribute.requires = new Array(attribute.requires_count); | ||
var provides_with_count = _entry2.provides_with_count; | ||
while (provides_with_count-- > 0) { | ||
_entry2.provides_with_index.push(this.buf.readUint16()); | ||
} | ||
for (var i = 0; i < attribute.requires_count; i++) { | ||
attribute.requires[i] = { | ||
requires_index: this.buf.readUint16(), | ||
requires_flags: this.buf.readUint16(), | ||
requires_version_index: this.buf.readUint16() | ||
}; | ||
} | ||
attribute.provides.push(_entry2); | ||
} | ||
break; | ||
} | ||
attribute.exports_count = this.buf.readUint16(); | ||
attribute.exports = new Array(attribute.exports_count); | ||
case 'ModulePackages': | ||
{ | ||
attribute.package_count = this.buf.readUint16(); | ||
attribute.package_index = []; | ||
for (var exportIndex = 0; exportIndex < attribute.exports_count; exportIndex++) { | ||
var exportEntry = { | ||
exports_index: this.buf.readUint16(), | ||
exports_flags: this.buf.readUint16(), | ||
exports_to_count: this.buf.readUint16() | ||
}; | ||
exportEntry.exports_to_index = new Array(exportEntry.exports_to_count); | ||
var package_count = attribute.package_count; | ||
while (package_count-- > 0) { | ||
attribute.package_index.push(this.buf.readUint16()); | ||
} | ||
break; | ||
} | ||
for (var exportsToIndex = 0; exportsToIndex < exportEntry.exports_to_count; exportsToIndex++) { | ||
exportEntry.exports_to_index[exportsToIndex] = this.buf.readUint16(); | ||
} | ||
/* Not specified in JVMS 9 */ | ||
case 'ModuleTarget': | ||
attribute.target_platform_index = this.buf.readUint16(); | ||
break; | ||
attribute.exports[exportIndex] = exportEntry; | ||
} | ||
case 'ModuleHashes': | ||
{ | ||
attribute.algorithm_index = this.buf.readUint16(); | ||
attribute.hashes_table_length = this.buf.readUint16(); | ||
attribute.hashes_table = []; | ||
attribute.opens_count = this.buf.readUint16(); | ||
attribute.opens = new Array(attribute.opens_count); | ||
var hashes_table_length = attribute.hashes_table_length; | ||
while (hashes_table_length-- > 0) { | ||
var _entry3 = { | ||
module_name_index: this.buf.readUint16(), | ||
hash_length: this.buf.readUint16(), | ||
hash: [] | ||
}; | ||
for (var openIndex = 0; openIndex < attribute.opens_count; openIndex++) { | ||
var openEntry = { | ||
opens_index: this.buf.readUint16(), | ||
opens_flags: this.buf.readUint16(), | ||
opens_to_count: this.buf.readUint16() | ||
}; | ||
openEntry.opens_to_index = new Array(openEntry.opens_to_count); | ||
var hash_length = _entry3.hash_length; | ||
while (hash_length-- > 0) { | ||
_entry3.hash.push(this.buf.readUInt8()); | ||
} | ||
for (var opensToIndex = 0; opensToIndex < openEntry.opens_to_count; opensToIndex++) { | ||
openEntry.opens_to_index[opensToIndex] = this.buf.readUint16(); | ||
} | ||
attribute.hashes_table.push(_entry3); | ||
} | ||
break; | ||
} | ||
/* -- */ | ||
attribute.opens[openIndex] = openEntry; | ||
} | ||
// Unknown attributes | ||
// See: https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.1 | ||
default: | ||
{ | ||
attribute.info = []; | ||
var _attribute_length = attribute.attribute_length; | ||
while (_attribute_length-- > 0) { | ||
attribute.info.push(this.buf.readUInt8()); | ||
} | ||
} | ||
attribute.uses_count = this.buf.readUint16(); | ||
attribute.uses_index = new Array(attribute.uses_count); | ||
; | ||
for (var _i15 = 0; _i15 < attribute.uses_count; _i15++) { | ||
attribute.uses_index[_i15] = this.buf.readUint16(); | ||
} | ||
attribute.provides_count = this.buf.readUint16(); | ||
attribute.provides = new Array(attribute.provides_count); | ||
for (var providesIndex = 0; providesIndex < attribute.provides_count; providesIndex++) { | ||
var provideEntry = { | ||
provides_index: this.buf.readUint16(), | ||
provides_with_count: this.buf.readUint16() | ||
}; | ||
provideEntry.provides_with_index = new Array(provideEntry.provides_with_count); | ||
for (var providesWithIndex = 0; providesWithIndex < provideEntry.provides_with_count; providesWithIndex++) { | ||
provideEntry.provides_with_index[providesWithIndex] = this.buf.readUint16(); | ||
} | ||
attribute.provides[providesIndex] = provideEntry; | ||
} | ||
return attribute; | ||
} | ||
}, { | ||
key: "_readModulePackagesAttribute", | ||
value: function _readModulePackagesAttribute(attribute) { | ||
attribute.package_count = this.buf.readUint16(); | ||
attribute.package_index = new Array(attribute.package_count); | ||
for (var i = 0; i < attribute.package_count; i++) { | ||
attribute.package_index[i] = this.buf.readUint16(); | ||
} | ||
return attribute; | ||
} | ||
/** | ||
@@ -824,20 +808,19 @@ * Reads the "annotation" structure | ||
}, { | ||
key: '_readAttributeAnnotation', | ||
key: "_readAttributeAnnotation", | ||
value: function _readAttributeAnnotation() { | ||
var annotation = { | ||
type_index: this.buf.readUint16(), | ||
num_element_value_pairs: this.buf.readUint16(), | ||
element_value_pairs: [] | ||
num_element_value_pairs: this.buf.readUint16() | ||
}; | ||
var len = annotation.num_element_value_pairs; | ||
while (len-- > 0) { | ||
var element = { | ||
annotation.element_value_pairs = new Array(annotation.num_element_value_pairs); | ||
for (var i = 0; i < annotation.num_element_value_pairs; i++) { | ||
annotation.element_value_pairs[i] = { | ||
element_name_index: this.buf.readUint16(), | ||
element_value: this._readElementValue() | ||
}; | ||
annotation.element_value_pairs.push(element); | ||
} | ||
return annotation; | ||
} | ||
/** | ||
@@ -849,3 +832,3 @@ * Reads the "element_value" structure | ||
}, { | ||
key: '_readElementValue', | ||
key: "_readElementValue", | ||
value: function _readElementValue() { | ||
@@ -856,6 +839,6 @@ var element_value = { | ||
}; | ||
/** | ||
* https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.16.1-130 | ||
*/ | ||
switch (element_value.tag) { | ||
@@ -878,11 +861,13 @@ case 101: | ||
// [ | ||
var array_value = { | ||
num_values: this.buf.readUInt16(), | ||
values: [] | ||
var num_values = this.buf.readUint16(); | ||
var values = new Array(num_values); | ||
for (var i = 0; i < num_values; i++) { | ||
values[i] = this._readElementValue(); | ||
} | ||
element_value.value.array_value = { | ||
num_values: num_values, | ||
values: values | ||
}; | ||
var num_values = array_value.num_values; | ||
while (num_values-- > 0) { | ||
array_value.values.push(this._readElementValue()); | ||
} | ||
element_value.value.array_value = array_value; | ||
break; | ||
@@ -897,9 +882,17 @@ } | ||
case 66: // B | ||
case 67: // C | ||
case 68: // D | ||
case 70: // F | ||
case 73: // I | ||
case 74: // J | ||
case 83: // S | ||
case 90: // Z | ||
case 115: | ||
@@ -911,3 +904,3 @@ // s | ||
default: | ||
throw Error('Unexpected tag: ' + element_value.tag); | ||
throw Error("Unexpected tag: ".concat(element_value.tag)); | ||
} | ||
@@ -918,11 +911,12 @@ | ||
}, { | ||
key: '_readInterfaces', | ||
value: function _readInterfaces(interface_count) { | ||
var entries = []; | ||
while (interface_count-- > 0) { | ||
entries.push(this.buf.readUint16()); | ||
key: "_readInterfaces", | ||
value: function _readInterfaces(interfaceCount) { | ||
var interfaces = new Array(interfaceCount); | ||
for (var i = 0; i < interfaceCount; i++) { | ||
interfaces[i] = this.buf.readUint16(); | ||
} | ||
return entries; | ||
return interfaces; | ||
} | ||
/** | ||
@@ -933,4 +927,4 @@ * https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 | ||
}, { | ||
key: '_readConstantPool', | ||
value: function _readConstantPool(pool_size) { | ||
key: "_readConstantPool", | ||
value: function _readConstantPool(poolCount) { | ||
/** | ||
@@ -940,7 +934,8 @@ * https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1 | ||
*/ | ||
var pool = [undefined]; | ||
while (pool_size-- > 0) { | ||
var pool = new Array(poolCount); | ||
for (var i = 1; i <= poolCount; i++) { | ||
var entry = this._readConstantPoolEntry(); | ||
pool.push(entry); | ||
pool[i] = entry; | ||
/** | ||
@@ -954,51 +949,63 @@ * https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5 | ||
*/ | ||
if (entry.tag === _constantType2.default.LONG || entry.tag === _constantType2.default.DOUBLE) { | ||
pool.push(undefined); | ||
pool_size--; | ||
if (entry.tag === _constantType["default"].LONG || entry.tag === _constantType["default"].DOUBLE) { | ||
pool[++i] = undefined; | ||
} | ||
} | ||
return pool; | ||
} | ||
}, { | ||
key: "_readUtf8PoolEntry", | ||
value: function _readUtf8PoolEntry(tag) { | ||
var length = this.buf.readUint16(); | ||
var bytes = new Array(length); | ||
/** @private */ | ||
for (var i = 0; i < length; i++) { | ||
bytes[i] = this.buf.readUint8(); | ||
} | ||
return { | ||
tag: tag, | ||
length: length, | ||
bytes: bytes | ||
}; | ||
} | ||
}, { | ||
key: '_readConstantPoolEntry', | ||
key: "_readConstantPoolEntry", | ||
value: function _readConstantPoolEntry() { | ||
var cp_info = { | ||
tag: this.buf.readUInt8() | ||
}; | ||
var tag = this.buf.readUint8(); | ||
switch (cp_info.tag) { | ||
case _constantType2.default.UTF8: | ||
{ | ||
var strLen = this.buf.readUint16(); | ||
cp_info.length = strLen; | ||
cp_info.bytes = []; | ||
while (strLen-- > 0) { | ||
cp_info.bytes.push(this.buf.readUInt8()); | ||
} | ||
break; | ||
} | ||
switch (tag) { | ||
case _constantType["default"].UTF8: | ||
return this._readUtf8PoolEntry(tag); | ||
case _constantType2.default.INTEGER: | ||
case _constantType2.default.FLOAT: | ||
cp_info.bytes = this.buf.readUint32(); | ||
break; | ||
case _constantType["default"].INTEGER: | ||
case _constantType["default"].FLOAT: | ||
return { | ||
tag: tag, | ||
bytes: this.buf.readUint32() | ||
}; | ||
case _constantType2.default.LONG: | ||
case _constantType2.default.DOUBLE: | ||
cp_info.high_bytes = this.buf.readUint32(); | ||
cp_info.low_bytes = this.buf.readUint32(); | ||
break; | ||
case _constantType["default"].LONG: | ||
case _constantType["default"].DOUBLE: | ||
return { | ||
tag: tag, | ||
high_bytes: this.buf.readUint32(), | ||
low_bytes: this.buf.readUint32() | ||
}; | ||
case _constantType2.default.PACKAGE: | ||
case _constantType2.default.MODULE: | ||
case _constantType2.default.CLASS: | ||
cp_info.name_index = this.buf.readUInt16(); | ||
break; | ||
case _constantType["default"].PACKAGE: | ||
case _constantType["default"].MODULE: | ||
case _constantType["default"].CLASS: | ||
return { | ||
tag: tag, | ||
name_index: this.buf.readUint16() | ||
}; | ||
case _constantType2.default.STRING: | ||
cp_info.string_index = this.buf.readUInt16(); | ||
break; | ||
case _constantType["default"].STRING: | ||
return { | ||
tag: tag, | ||
string_index: this.buf.readUint16() | ||
}; | ||
@@ -1009,31 +1016,43 @@ /** | ||
*/ | ||
case _constantType2.default.FIELDREF: | ||
case _constantType2.default.METHODREF: | ||
case _constantType2.default.INTERFACE_METHODREF: | ||
cp_info.class_index = this.buf.readUint16(), cp_info.name_and_type_index = this.buf.readUint16(); | ||
break; | ||
case _constantType2.default.NAME_AND_TYPE: | ||
cp_info.name_index = this.buf.readUint16(); | ||
cp_info.descriptor_index = this.buf.readUint16(); | ||
break; | ||
case _constantType["default"].FIELDREF: | ||
case _constantType["default"].METHODREF: | ||
case _constantType["default"].INTERFACE_METHODREF: | ||
return { | ||
tag: tag, | ||
class_index: this.buf.readUint16(), | ||
name_and_type_index: this.buf.readUint16() | ||
}; | ||
case _constantType2.default.METHOD_HANDLE: | ||
cp_info.reference_kind = this.buf.readUint8(); | ||
cp_info.reference_index = this.buf.readUint16(); | ||
break; | ||
case _constantType["default"].NAME_AND_TYPE: | ||
return { | ||
tag: tag, | ||
name_index: this.buf.readUint16(), | ||
descriptor_index: this.buf.readUint16() | ||
}; | ||
case _constantType2.default.METHOD_TYPE: | ||
cp_info.descriptor_index = this.buf.readUInt16(); | ||
break; | ||
case _constantType["default"].METHOD_HANDLE: | ||
return { | ||
tag: tag, | ||
reference_kind: this.buf.readUint8(), | ||
reference_index: this.buf.readUint16() | ||
}; | ||
case _constantType2.default.INVOKE_DYNAMIC: | ||
cp_info.bootstrap_method_attr_index = this.buf.readUint16(); | ||
cp_info.name_and_type_index = this.buf.readUint16(); | ||
break; | ||
case _constantType["default"].METHOD_TYPE: | ||
return { | ||
tag: tag, | ||
descriptor_index: this.buf.readUint16() | ||
}; | ||
case _constantType["default"].DYNAMIC: | ||
case _constantType["default"].INVOKE_DYNAMIC: | ||
return { | ||
tag: tag, | ||
bootstrap_method_attr_index: this.buf.readUint16(), | ||
name_and_type_index: this.buf.readUint16() | ||
}; | ||
default: | ||
throw Error('Unexpected tag: ' + cp_info.tag); | ||
throw Error("Unexpected tag: ".concat(tag)); | ||
} | ||
return cp_info; | ||
} | ||
@@ -1045,2 +1064,3 @@ }]); | ||
module.exports = JavaClassFileReader; | ||
var _default = JavaClassFileReader; | ||
exports["default"] = _default; |
@@ -1,21 +0,19 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*! | ||
* https://github.com/leonardosnt/java-class-tools | ||
* | ||
* Copyright (C) 2017 leonardosnt | ||
* Licensed under the MIT License. See LICENSE file in the project root for full license information. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _bytebuffer = require('bytebuffer'); | ||
var _bytebuffer = _interopRequireDefault(require("bytebuffer")); | ||
var _bytebuffer2 = _interopRequireDefault(_bytebuffer); | ||
var _constantType = _interopRequireDefault(require("./constant-type")); | ||
var _constantType = require('./constant-type'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _constantType2 = _interopRequireDefault(_constantType); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
@@ -27,3 +25,5 @@ /** | ||
*/ | ||
var JavaClassFileWriter = function () { | ||
var JavaClassFileWriter = | ||
/*#__PURE__*/ | ||
function () { | ||
function JavaClassFileWriter() { | ||
@@ -34,5 +34,4 @@ _classCallCheck(this, JavaClassFileWriter); | ||
_createClass(JavaClassFileWriter, [{ | ||
key: 'write', | ||
key: "write", | ||
/** | ||
@@ -47,5 +46,4 @@ * Write ClassFile object to a ByteBuffer. | ||
value: function write(classFile) { | ||
this.buf = new _bytebuffer2.default(); | ||
this.buf = new _bytebuffer["default"](); | ||
this.classFile = classFile; | ||
this.buf.writeUint8(0xCA); | ||
@@ -55,7 +53,6 @@ this.buf.writeUint8(0xFE); | ||
this.buf.writeUint8(0xBE); | ||
this.buf.writeUint16(classFile.minor_version); | ||
this.buf.writeUint16(classFile.major_version); | ||
this.buf.writeUint16(classFile.constant_pool_count); | ||
this.buf.writeUint16(classFile.constant_pool_count); | ||
this._writeConstantPool(classFile.constant_pool); | ||
@@ -66,13 +63,16 @@ | ||
this.buf.writeUint16(classFile.super_class); | ||
this.buf.writeUint16(classFile.interfaces_count); | ||
this.buf.writeUint16(classFile.interfaces_count); | ||
this._writeInterfaces(classFile.interfaces); | ||
this.buf.writeUint16(classFile.fields_count); | ||
this._writeCommonFieldMethodArray(classFile.fields); | ||
this._writeMemberInfoArray(classFile.fields); | ||
this.buf.writeUint16(classFile.methods_count); | ||
this._writeCommonFieldMethodArray(classFile.methods); | ||
this._writeMemberInfoArray(classFile.methods); | ||
this.buf.writeUint16(classFile.attributes_count); | ||
this._writeAttributeInfoArray(classFile.attributes); | ||
@@ -84,7 +84,6 @@ | ||
}, { | ||
key: '_writeCommonFieldMethodArray', | ||
value: function _writeCommonFieldMethodArray(array) { | ||
key: "_writeMemberInfoArray", | ||
value: function _writeMemberInfoArray(array) { | ||
for (var i = 0; i < array.length; i++) { | ||
var entry = array[i]; | ||
this.buf.writeUint16(entry.access_flags); | ||
@@ -94,2 +93,3 @@ this.buf.writeUint16(entry.name_index); | ||
this.buf.writeUint16(entry.attributes_count); | ||
this._writeAttributeInfoArray(entry.attributes); | ||
@@ -99,3 +99,3 @@ } | ||
}, { | ||
key: '_writeAttributeInfoArray', | ||
key: "_writeAttributeInfoArray", | ||
value: function _writeAttributeInfoArray(attributes) { | ||
@@ -107,3 +107,3 @@ for (var i = 0; i < attributes.length; i++) { | ||
}, { | ||
key: '_writeAttributeAnnotation', | ||
key: "_writeAttributeAnnotation", | ||
value: function _writeAttributeAnnotation(annotation) { | ||
@@ -115,4 +115,4 @@ this.buf.writeUint16(annotation.type_index); | ||
var element = annotation.element_value_pairs[i]; | ||
this.buf.writeUint16(element.element_name_index); | ||
this.buf.writeUint16(element.element_name_index); | ||
this._writeElementValue(element.element_value); | ||
@@ -122,7 +122,7 @@ } | ||
}, { | ||
key: '_writeElementValue', | ||
key: "_writeElementValue", | ||
value: function _writeElementValue(element_value) { | ||
this.buf.writeUint8(element_value.tag); | ||
var value = element_value.value; | ||
var value = element_value.value; | ||
switch (element_value.tag) { | ||
@@ -147,2 +147,3 @@ case 101: | ||
} | ||
break; | ||
@@ -152,12 +153,21 @@ | ||
this._writeAttributeAnnotation(value.annotation); | ||
break; | ||
case 66: // B | ||
case 67: // C | ||
case 68: // D | ||
case 70: // F | ||
case 73: // I | ||
case 74: // J | ||
case 83: // S | ||
case 90: // Z | ||
case 115: | ||
@@ -169,7 +179,7 @@ // s | ||
default: | ||
throw Error('Unexpected tag: ' + element_value.tag); | ||
throw Error("Unexpected tag: ".concat(element_value.tag)); | ||
} | ||
} | ||
}, { | ||
key: '_writeTypeAnnotation', | ||
key: "_writeTypeAnnotation", | ||
value: function _writeTypeAnnotation(type_annotation) { | ||
@@ -180,33 +190,38 @@ this.buf.writeUint8(type_annotation.target_type); | ||
// type_parameter_target | ||
case 0x00:case 0x01: | ||
case 0x00: | ||
case 0x01: | ||
this.buf.writeUint8(type_annotation.target_info.type_parameter_index); | ||
break; | ||
// supertype_target | ||
// supertype_target | ||
case 0x10: | ||
this.buf.writeUint16(type_annotation.target_info.supertype_index); | ||
break; | ||
// type_parameter_bound_target | ||
// type_parameter_bound_target | ||
case 0x11:case 0x12: | ||
case 0x11: | ||
case 0x12: | ||
this.buf.writeUint8(type_annotation.target_info.type_parameter_index); | ||
this.buf.writeUint8(type_annotation.target_info.bound_index); | ||
break; | ||
// empty_target | ||
// empty_target | ||
case 0x13:case 0x14:case 0x15: | ||
case 0x13: | ||
case 0x14: | ||
case 0x15: | ||
break; | ||
// formal_parameter_target | ||
// formal_parameter_target | ||
case 0x16: | ||
this.buf.writeUint8(type_annotation.target_info.formal_parameter_index); | ||
break; | ||
// throws_target | ||
// throws_target | ||
case 0x17: | ||
this.buf.writeUint16(type_annotation.target_info.throws_type_index); | ||
break; | ||
// localvar_target | ||
// localvar_target | ||
case 0x40:case 0x41: | ||
case 0x40: | ||
case 0x41: | ||
this.buf.writeUint16(type_annotation.target_info.table_length); | ||
@@ -216,3 +231,2 @@ | ||
var table_entry = type_annotation.target_info.table[i]; | ||
this.buf.writeUint16(table_entry.start_pc); | ||
@@ -222,16 +236,24 @@ this.buf.writeUint16(table_entry.length); | ||
} | ||
break; | ||
// catch_target | ||
// catch_target | ||
case 0x42: | ||
this.buf.writeUint16(type_annotation.target_info.exception_table_index); | ||
break; | ||
// offset_target | ||
// offset_target | ||
case 0x43:case 0x44:case 0x45:case 0x46: | ||
case 0x43: | ||
case 0x44: | ||
case 0x45: | ||
case 0x46: | ||
this.buf.writeUint16(type_annotation.target_info.offset); | ||
break; | ||
// type_argument_target | ||
// type_argument_target | ||
case 0x47:case 0x48:case 0x49:case 0x4A:case 0x4B: | ||
case 0x47: | ||
case 0x48: | ||
case 0x49: | ||
case 0x4A: | ||
case 0x4B: | ||
this.buf.writeUint16(type_annotation.target_info.offset); | ||
@@ -242,3 +264,3 @@ this.buf.writeUint8(type_annotation.target_info.type_argument_index); | ||
default: | ||
throw Error('Unexpected target_type: ' + type_annotation.target_type); | ||
throw Error("Unexpected target_type: ".concat(type_annotation.target_type)); | ||
} | ||
@@ -250,3 +272,2 @@ | ||
var path_entry = type_annotation.type_path.path[i]; | ||
this.buf.writeUint8(path_entry.type_path_kind); | ||
@@ -261,4 +282,4 @@ this.buf.writeUint8(path_entry.type_argument_index); | ||
var element_value_entry = type_annotation.element_value_pairs[i]; | ||
this.buf.writeUint16(element_value_entry.element_name_index); | ||
this.buf.writeUint16(element_value_entry.element_name_index); | ||
this._writeElementValue(element_value_entry.element_value); | ||
@@ -268,8 +289,7 @@ } | ||
}, { | ||
key: '_writeAttributeInfo', | ||
value: function _writeAttributeInfo(attribute_info) { | ||
this.buf.writeUint16(attribute_info.attribute_name_index); | ||
this.buf.writeUint32(attribute_info.attribute_length); | ||
var attributeNameBytes = this.classFile.constant_pool[attribute_info.attribute_name_index].bytes; | ||
key: "_writeAttributeInfo", | ||
value: function _writeAttributeInfo(attribute) { | ||
this.buf.writeUint16(attribute.attribute_name_index); | ||
this.buf.writeUint32(attribute.attribute_length); | ||
var attributeNameBytes = this.classFile.constant_pool[attribute.attribute_name_index].bytes; | ||
var attributeName = String.fromCharCode.apply(null, attributeNameBytes); // TODO: is this safe? | ||
@@ -280,10 +300,11 @@ | ||
case 'RuntimeVisibleAnnotations': | ||
this.buf.writeUint16(attribute_info.num_annotations); | ||
this.buf.writeUint16(attribute.num_annotations); | ||
for (var i = 0; i < attribute_info.num_annotations; i++) { | ||
this._writeAttributeAnnotation(attribute_info.annotations[i]); | ||
for (var i = 0; i < attribute.num_annotations; i++) { | ||
this._writeAttributeAnnotation(attribute.annotations[i]); | ||
} | ||
break; | ||
// There's no additional information | ||
// There's no additional information | ||
case 'Deprecated': | ||
@@ -294,7 +315,6 @@ case 'Synthetic': | ||
case 'InnerClasses': | ||
this.buf.writeUint16(attribute_info.number_of_classes); | ||
this.buf.writeUint16(attribute.number_of_classes); | ||
for (var i = 0; i < attribute_info.number_of_classes; i++) { | ||
var inner_class = attribute_info.classes[i]; | ||
for (var i = 0; i < attribute.number_of_classes; i++) { | ||
var inner_class = attribute.classes[i]; | ||
this.buf.writeUint16(inner_class.inner_class_info_index); | ||
@@ -305,10 +325,10 @@ this.buf.writeUint16(inner_class.outer_class_info_index); | ||
} | ||
break; | ||
case 'LocalVariableTable': | ||
this.buf.writeUint16(attribute_info.local_variable_table_length); | ||
this.buf.writeUint16(attribute.local_variable_table_length); | ||
for (var i = 0; i < attribute_info.local_variable_table_length; i++) { | ||
var local_variable = attribute_info.local_variable_table[i]; | ||
for (var i = 0; i < attribute.local_variable_table_length; i++) { | ||
var local_variable = attribute.local_variable_table[i]; | ||
this.buf.writeUint16(local_variable.start_pc); | ||
@@ -320,10 +340,10 @@ this.buf.writeUint16(local_variable.length); | ||
} | ||
break; | ||
case 'LocalVariableTypeTable': | ||
this.buf.writeUint16(attribute_info.local_variable_type_table_length); | ||
this.buf.writeUint16(attribute.local_variable_type_table_length); | ||
for (var i = 0; i < attribute_info.local_variable_type_table_length; i++) { | ||
var local_variable_type = attribute_info.local_variable_type_table[i]; | ||
for (var i = 0; i < attribute.local_variable_type_table_length; i++) { | ||
var local_variable_type = attribute.local_variable_type_table[i]; | ||
this.buf.writeUint16(local_variable_type.start_pc); | ||
@@ -335,2 +355,3 @@ this.buf.writeUint16(local_variable_type.length); | ||
} | ||
break; | ||
@@ -340,6 +361,6 @@ | ||
case 'RuntimeVisibleParameterAnnotations': | ||
this.buf.writeUint8(attribute_info.num_parameters); | ||
this.buf.writeUint8(attribute.num_parameters); | ||
for (var i = 0; i < attribute_info.num_parameters; i++) { | ||
var parameter_annotation = attribute_info.parameter_annotations[i]; | ||
for (var i = 0; i < attribute.num_parameters; i++) { | ||
var parameter_annotation = attribute.parameter_annotations[i]; | ||
this.buf.writeUint16(parameter_annotation.num_annotations); | ||
@@ -351,10 +372,10 @@ | ||
} | ||
break; | ||
case 'BootstrapMethods': | ||
this.buf.writeUint16(attribute_info.num_bootstrap_methods); | ||
this.buf.writeUint16(attribute.num_bootstrap_methods); | ||
for (var i = 0; i < attribute_info.num_bootstrap_methods; i++) { | ||
var bootstrap_method = attribute_info.bootstrap_methods[i]; | ||
for (var i = 0; i < attribute.num_bootstrap_methods; i++) { | ||
var bootstrap_method = attribute.bootstrap_methods[i]; | ||
this.buf.writeUint16(bootstrap_method.bootstrap_method_ref); | ||
@@ -367,2 +388,3 @@ this.buf.writeUint16(bootstrap_method.num_bootstrap_arguments); | ||
} | ||
break; | ||
@@ -372,53 +394,57 @@ | ||
case 'RuntimeVisibleTypeAnnotations': | ||
this.buf.writeUint16(attribute_info.num_annotations); | ||
this.buf.writeUint16(attribute.num_annotations); | ||
for (var i = 0; i < attribute_info.num_annotations; i++) { | ||
this._writeTypeAnnotation(attribute_info.annotations[i]); | ||
for (var i = 0; i < attribute.num_annotations; i++) { | ||
this._writeTypeAnnotation(attribute.annotations[i]); | ||
} | ||
break; | ||
case 'SourceDebugExtension': | ||
for (var i = 0; i < attribute_info.attribute_length; i++) { | ||
this.buf.writeUint8(attribute_info.debug_extension[i]); | ||
for (var i = 0; i < attribute.attribute_length; i++) { | ||
this.buf.writeUint8(attribute.debug_extension[i]); | ||
} | ||
break; | ||
case 'SourceFile': | ||
this.buf.writeUint16(attribute_info.sourcefile_index); | ||
this.buf.writeUint16(attribute.sourcefile_index); | ||
break; | ||
case 'EnclosingMethod': | ||
this.buf.writeUint16(attribute_info.class_index); | ||
this.buf.writeUint16(attribute_info.method_index); | ||
this.buf.writeUint16(attribute.class_index); | ||
this.buf.writeUint16(attribute.method_index); | ||
break; | ||
case 'AnnotationDefault': | ||
this._writeElementValue(attribute_info.default_value); | ||
this._writeElementValue(attribute.default_value); | ||
break; | ||
case 'MethodParameters': | ||
this.buf.writeUint16(attribute_info.parameters_count); | ||
this.buf.writeUint8(attribute.parameters_count); | ||
for (var i = 0; i < attribute_info.parameters_count; i++) { | ||
var parameter = attribute_info.parameters[i]; | ||
for (var i = 0; i < attribute.parameters_count; i++) { | ||
var parameter = attribute.parameters[i]; | ||
this.buf.writeUint16(parameter.name_index); | ||
this.buf.writeUint16(parameter.access_flags); | ||
} | ||
break; | ||
case 'Exceptions': | ||
this.buf.writeUint16(attribute_info.number_of_exceptions); | ||
this.buf.writeUint16(attribute.number_of_exceptions); | ||
for (var i = 0; i < attribute_info.number_of_exceptions; i++) { | ||
this.buf.writeUint16(attribute_info.exception_index_table[i]); | ||
for (var i = 0; i < attribute.number_of_exceptions; i++) { | ||
this.buf.writeUint16(attribute.exception_index_table[i]); | ||
} | ||
break; | ||
case 'ConstantValue': | ||
this.buf.writeUint16(attribute_info.constantvalue_index); | ||
this.buf.writeUint16(attribute.constantvalue_index); | ||
break; | ||
case 'Signature': | ||
this.buf.writeUint16(attribute_info.signature_index); | ||
this.buf.writeUint16(attribute.signature_index); | ||
break; | ||
@@ -428,33 +454,28 @@ | ||
{ | ||
this.buf.writeUint16(attribute_info.number_of_entries); | ||
this.buf.writeUint16(attribute.number_of_entries); | ||
for (var i = 0; i < attribute_info.number_of_entries; i++) { | ||
var stack_map_frame = attribute_info.entries[i]; | ||
for (var i = 0; i < attribute.number_of_entries; i++) { | ||
var stack_map_frame = attribute.entries[i]; | ||
var frame_type = stack_map_frame.frame_type; | ||
this.buf.writeUint8(frame_type); // SAME_LOCALS_1_STACK_ITEM | ||
this.buf.writeUint8(frame_type); | ||
// SAME_LOCALS_1_STACK_ITEM | ||
if (frame_type >= 64 && frame_type <= 127) { | ||
this._writeVerificationTypeInfo(stack_map_frame.stack[0]); | ||
} | ||
// SAME_LOCALS_1_STACK_ITEM_EXTENDED | ||
} // SAME_LOCALS_1_STACK_ITEM_EXTENDED | ||
else if (stack_map_frame.frame_type === 247) { | ||
this.buf.writeUint16(stack_map_frame.offset_delta); | ||
this._writeVerificationTypeInfo(stack_map_frame.stack[0]); | ||
} | ||
// CHOP = 248-250, SAME_FRAME_EXTENDED = 251 | ||
} // CHOP = 248-250, SAME_FRAME_EXTENDED = 251 | ||
else if (frame_type >= 248 && frame_type <= 251) { | ||
this.buf.writeUint16(stack_map_frame.offset_delta); | ||
} | ||
// APPEND | ||
} // APPEND | ||
else if (frame_type >= 252 && frame_type <= 254) { | ||
this.buf.writeUint16(stack_map_frame.offset_delta); | ||
var number_of_locals = frame_type - 251; | ||
var number_of_locals = frame_type - 251; | ||
for (var j = 0; j < number_of_locals; j++) { | ||
this._writeVerificationTypeInfo(stack_map_frame.locals[j]); | ||
} | ||
} | ||
// FULL_FRAME | ||
} // FULL_FRAME | ||
else if (frame_type === 255) { | ||
@@ -475,2 +496,3 @@ this.buf.writeUint16(stack_map_frame.offset_delta); | ||
} | ||
break; | ||
@@ -480,15 +502,14 @@ } | ||
case 'Code': | ||
this.buf.writeUint16(attribute_info.max_stack); | ||
this.buf.writeUint16(attribute_info.max_locals); | ||
this.buf.writeUint32(attribute_info.code_length); | ||
this.buf.writeUint16(attribute.max_stack); | ||
this.buf.writeUint16(attribute.max_locals); | ||
this.buf.writeUint32(attribute.code_length); | ||
for (var i = 0; i < attribute_info.code_length; i++) { | ||
this.buf.writeUint8(attribute_info.code[i]); | ||
for (var i = 0; i < attribute.code_length; i++) { | ||
this.buf.writeUint8(attribute.code[i]); | ||
} | ||
this.buf.writeUint16(attribute_info.exception_table_length); | ||
this.buf.writeUint16(attribute.exception_table_length); | ||
for (var i = 0; i < attribute_info.exception_table_length; i++) { | ||
var exception_entry = attribute_info.exception_table[i]; | ||
for (var i = 0; i < attribute.exception_table_length; i++) { | ||
var exception_entry = attribute.exception_table[i]; | ||
this.buf.writeUint16(exception_entry.start_pc); | ||
@@ -500,15 +521,17 @@ this.buf.writeUint16(exception_entry.end_pc); | ||
this.buf.writeUint16(attribute_info.attributes_count); | ||
this._writeAttributeInfoArray(attribute_info.attributes); | ||
this.buf.writeUint16(attribute.attributes_count); | ||
this._writeAttributeInfoArray(attribute.attributes); | ||
break; | ||
case 'LineNumberTable': | ||
this.buf.writeUint16(attribute_info.line_number_table_length); | ||
this.buf.writeUint16(attribute.line_number_table_length); | ||
for (var i = 0; i < attribute_info.line_number_table_length; i++) { | ||
var line_number = attribute_info.line_number_table[i]; | ||
for (var i = 0; i < attribute.line_number_table_length; i++) { | ||
var line_number = attribute.line_number_table[i]; | ||
this.buf.writeUint16(line_number.start_pc); | ||
this.buf.writeUint16(line_number.line_number); | ||
} | ||
break; | ||
@@ -518,10 +541,9 @@ | ||
{ | ||
this.buf.writeUint16(attribute_info.module_name_index); | ||
this.buf.writeUint16(attribute_info.module_flags); | ||
this.buf.writeUint16(attribute_info.module_version_index); | ||
this.buf.writeUint16(attribute.module_name_index); | ||
this.buf.writeUint16(attribute.module_flags); | ||
this.buf.writeUint16(attribute.module_version_index); | ||
this.buf.writeUint16(attribute.requires_count); | ||
this.buf.writeUint16(attribute_info.requires_count); | ||
for (var i = 0; i < attribute_info.requires_count; i++) { | ||
var entry = attribute_info.requires[i]; | ||
for (var i = 0; i < attribute.requires_count; i++) { | ||
var entry = attribute.requires[i]; | ||
this.buf.writeUint16(entry.requires_index); | ||
@@ -532,6 +554,6 @@ this.buf.writeUint16(entry.requires_flags); | ||
this.buf.writeUint16(attribute_info.exports_count); | ||
for (var i = 0; i < attribute_info.exports_count; i++) { | ||
var _entry = attribute_info.exports[i]; | ||
this.buf.writeUint16(attribute.exports_count); | ||
for (var i = 0; i < attribute.exports_count; i++) { | ||
var _entry = attribute.exports[i]; | ||
this.buf.writeUint16(_entry.exports_index); | ||
@@ -546,6 +568,6 @@ this.buf.writeUint16(_entry.exports_flags); | ||
this.buf.writeUint16(attribute_info.opens_count); | ||
for (var i = 0; i < attribute_info.opens_count; i++) { | ||
var _entry2 = attribute_info.opens[i]; | ||
this.buf.writeUint16(attribute.opens_count); | ||
for (var i = 0; i < attribute.opens_count; i++) { | ||
var _entry2 = attribute.opens[i]; | ||
this.buf.writeUint16(_entry2.opens_index); | ||
@@ -560,11 +582,12 @@ this.buf.writeUint16(_entry2.opens_flags); | ||
this.buf.writeUint16(attribute_info.uses_count); | ||
for (var i = 0; i < attribute_info.uses_count; i++) { | ||
this.buf.writeUint16(attribute_info.uses_index[i]); | ||
this.buf.writeUint16(attribute.uses_count); | ||
for (var i = 0; i < attribute.uses_count; i++) { | ||
this.buf.writeUint16(attribute.uses_index[i]); | ||
} | ||
this.buf.writeUint16(attribute_info.provides_count); | ||
for (var i = 0; i < attribute_info.provides_count; i++) { | ||
var _entry3 = attribute_info.provides[i]; | ||
this.buf.writeUint16(attribute.provides_count); | ||
for (var i = 0; i < attribute.provides_count; i++) { | ||
var _entry3 = attribute.provides[i]; | ||
this.buf.writeUint16(_entry3.provides_index); | ||
@@ -577,2 +600,3 @@ this.buf.writeUint16(_entry3.provides_with_count); | ||
} | ||
break; | ||
@@ -582,37 +606,33 @@ } | ||
case 'ModulePackages': | ||
this.buf.writeUint16(attribute_info.package_count); | ||
for (var i = 0; i < attribute_info.package_count; i++) { | ||
this.buf.writeUint16(attribute_info.package_index[i]); | ||
this.buf.writeUint16(attribute.package_count); | ||
for (var i = 0; i < attribute.package_count; i++) { | ||
this.buf.writeUint16(attribute.package_index[i]); | ||
} | ||
break; | ||
/* Not specified in JVMS 9 */ | ||
case 'ModuleTarget': | ||
this.buf.writeUint16(attribute_info.target_platform_index); | ||
case 'ModuleMainClass': | ||
this.buf.writeUint16(attribute.main_class_index); | ||
break; | ||
case 'ModuleHashes': | ||
{ | ||
this.buf.writeUint16(attribute_info.algorithm_index); | ||
this.buf.writeUint16(attribute_info.hashes_table_length); | ||
case 'NestHost': | ||
this.buf.writeUint16(attribute.host_class_index); | ||
break; | ||
for (var i = 0; i < attribute_info.hashes_table_length; i++) { | ||
var _entry4 = attribute_info.hashes_table[i]; | ||
this.buf.writeUint16(_entry4.module_name_index); | ||
this.buf.writeUint16(_entry4.hash_length); | ||
case 'NestMembers': | ||
this.buf.writeUint16(attribute.number_of_classes); | ||
for (var j = 0; j < _entry4.hash_length; j++) { | ||
this.buf.writeUint8(_entry4.hash[j]); | ||
} | ||
} | ||
break; | ||
for (var _i = 0; _i < attribute.number_of_classes; _i++) { | ||
this.buf.writeUint16(attribute.classes[_i]); | ||
} | ||
/* -- */ | ||
break; | ||
// Unknown attributes | ||
// See: https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.1 | ||
default: | ||
{ | ||
for (var i = 0; i < attribute_info.attribute_length; i++) { | ||
this.buf.writeUint8(attribute_info.info[i]); | ||
for (var i = 0; i < attribute.attribute_length; i++) { | ||
this.buf.writeUint8(attribute.info[i]); | ||
} | ||
@@ -623,5 +643,6 @@ } | ||
}, { | ||
key: '_writeVerificationTypeInfo', | ||
key: "_writeVerificationTypeInfo", | ||
value: function _writeVerificationTypeInfo(type_info) { | ||
this.buf.writeUint8(type_info.tag); | ||
if (type_info.tag === 7) { | ||
@@ -634,3 +655,3 @@ this.buf.writeUint16(type_info.cpool_index); | ||
}, { | ||
key: '_writeInterfaces', | ||
key: "_writeInterfaces", | ||
value: function _writeInterfaces(interfaces) { | ||
@@ -642,3 +663,3 @@ for (var i = 0; i < interfaces.length; i++) { | ||
}, { | ||
key: '_writeConstantPool', | ||
key: "_writeConstantPool", | ||
value: function _writeConstantPool(constant_pool) { | ||
@@ -654,3 +675,3 @@ for (var i = 1; i < constant_pool.length; i++) { | ||
}, { | ||
key: '_writeConstantPoolEntry', | ||
key: "_writeConstantPoolEntry", | ||
value: function _writeConstantPoolEntry(entry) { | ||
@@ -660,3 +681,3 @@ this.buf.writeUint8(entry.tag); | ||
switch (entry.tag) { | ||
case _constantType2.default.UTF8: | ||
case _constantType["default"].UTF8: | ||
{ | ||
@@ -668,12 +689,13 @@ this.buf.writeUint16(entry.length); | ||
} | ||
break; | ||
} | ||
case _constantType2.default.INTEGER: | ||
case _constantType2.default.FLOAT: | ||
case _constantType["default"].INTEGER: | ||
case _constantType["default"].FLOAT: | ||
this.buf.writeUint32(entry.bytes); | ||
break; | ||
case _constantType2.default.LONG: | ||
case _constantType2.default.DOUBLE: | ||
case _constantType["default"].LONG: | ||
case _constantType["default"].DOUBLE: | ||
this.buf.writeUint32(entry.high_bytes); | ||
@@ -683,15 +705,15 @@ this.buf.writeUint32(entry.low_bytes); | ||
case _constantType2.default.PACKAGE: | ||
case _constantType2.default.MODULE: | ||
case _constantType2.default.CLASS: | ||
case _constantType["default"].PACKAGE: | ||
case _constantType["default"].MODULE: | ||
case _constantType["default"].CLASS: | ||
this.buf.writeUint16(entry.name_index); | ||
break; | ||
case _constantType2.default.STRING: | ||
case _constantType["default"].STRING: | ||
this.buf.writeUint16(entry.string_index); | ||
break; | ||
case _constantType2.default.FIELDREF: | ||
case _constantType2.default.METHODREF: | ||
case _constantType2.default.INTERFACE_METHODREF: | ||
case _constantType["default"].FIELDREF: | ||
case _constantType["default"].METHODREF: | ||
case _constantType["default"].INTERFACE_METHODREF: | ||
this.buf.writeUint16(entry.class_index); | ||
@@ -701,3 +723,3 @@ this.buf.writeUint16(entry.name_and_type_index); | ||
case _constantType2.default.NAME_AND_TYPE: | ||
case _constantType["default"].NAME_AND_TYPE: | ||
this.buf.writeUint16(entry.name_index); | ||
@@ -707,3 +729,3 @@ this.buf.writeUint16(entry.descriptor_index); | ||
case _constantType2.default.METHOD_HANDLE: | ||
case _constantType["default"].METHOD_HANDLE: | ||
this.buf.writeUint8(entry.reference_kind); | ||
@@ -713,7 +735,8 @@ this.buf.writeUint16(entry.reference_index); | ||
case _constantType2.default.METHOD_TYPE: | ||
case _constantType["default"].METHOD_TYPE: | ||
this.buf.writeUint16(entry.descriptor_index); | ||
break; | ||
case _constantType2.default.INVOKE_DYNAMIC: | ||
case _constantType["default"].DYNAMIC: | ||
case _constantType["default"].INVOKE_DYNAMIC: | ||
this.buf.writeUint16(entry.bootstrap_method_attr_index); | ||
@@ -724,3 +747,3 @@ this.buf.writeUint16(entry.name_and_type_index); | ||
default: | ||
throw Error('Unexpected tag: ' + entry.tag); | ||
throw Error("Unexpected tag: ".concat(entry.tag)); | ||
} | ||
@@ -733,2 +756,3 @@ } | ||
module.exports = JavaClassFileWriter; | ||
var _default = JavaClassFileWriter; | ||
exports["default"] = _default; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
/*! | ||
@@ -9,3 +14,2 @@ * https://github.com/leonardosnt/java-class-tools | ||
*/ | ||
var Modifier = { | ||
@@ -26,3 +30,2 @@ PUBLIC: 0x0001, | ||
SYNTHETIC: 0x1000, | ||
// Class only | ||
@@ -33,7 +36,6 @@ INTERFACE: 0x0200, | ||
ENUM: 0x4000, | ||
// Java SE 9 | ||
MODULE: 0x8000 | ||
}; | ||
module.exports = Modifier; | ||
var _default = Modifier; | ||
exports["default"] = _default; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
/*! | ||
@@ -9,3 +14,2 @@ * https://github.com/leonardosnt/java-class-tools | ||
*/ | ||
var Opcode = { | ||
@@ -218,3 +222,3 @@ NOP: 0x0, | ||
}; | ||
module.exports = Opcode; | ||
var _default = Opcode; | ||
exports["default"] = _default; |
{ | ||
"name": "java-class-tools", | ||
"version": "1.3.1", | ||
"version": "1.3.2", | ||
"description": "Read and write java class files in node or browser.", | ||
@@ -23,3 +23,3 @@ "main": "lib/index.js", | ||
"parser", | ||
"decompíler", | ||
"decompiler", | ||
"reader", | ||
@@ -37,23 +37,25 @@ "writer", | ||
"test": "mocha test/tests.js", | ||
"build": "gulp" | ||
"build": "gulp", | ||
"watch": "gulp watch" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.22.2", | ||
"babel-core": "^6.22.1", | ||
"babel-loader": "^6.2.10", | ||
"babel-preset-es2015": "^6.22.0", | ||
"deep-equal": "^1.0.1", | ||
"fs-extra": "^2.0.0", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2", | ||
"gulp-cli": "^1.2.2", | ||
"@babel/core": "^7.6.4", | ||
"@babel/preset-env": "^7.6.3", | ||
"@types/bytebuffer": "^5.0.1", | ||
"@types/node": "^7.0.18", | ||
"babel-loader": "^8.0.6", | ||
"fs-extra": "^8.1.0", | ||
"gulp": "^4.0.2", | ||
"gulp-babel": "^8.0.0", | ||
"gulp-cli": "^2.2.0", | ||
"gulp-insert": "^0.5.0", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-uglifyjs": "^0.6.2", | ||
"jszip": "^3.1.3", | ||
"mocha": "^3.2.0", | ||
"tmp": "^0.0.31", | ||
"webpack-stream": "^3.2.0", | ||
"@types/bytebuffer": "^5.0.1", | ||
"@types/node": "^7.0.18" | ||
"gulp-rename": "^1.4.0", | ||
"gulp-uglify": "^3.0.2", | ||
"jszip": "^3.2.2", | ||
"mocha": "^6.2.2", | ||
"tmp": "^0.1.0", | ||
"utf8-string-bytes": "^1.0.3", | ||
"webpack": "^4.41.2", | ||
"webpack-cli": "^3.3.9", | ||
"webpack-stream": "^5.2.1" | ||
}, | ||
@@ -60,0 +62,0 @@ "dependencies": { |
@@ -13,6 +13,5 @@ # java-class-tools | ||
## Examples: | ||
- [Live example](https://rawgit.com/leonardosnt/java-class-tools/master/examples/browser.html) | ||
- [Listing Instructions](https://esnextb.in/?gist=6981727ba2ec87dea369be5c5b82f8a2&execute=true) (Using the [InstructionParser](https://github.com/leonardosnt/java-class-tools/blob/master/src/instruction-parser.js#L54)) | ||
- [Try yourself](https://esnextb.in/?gist=3ad904c5497aad3d27c333c897374d54&execute=true) (ESNextbin) | ||
- [Try yourself](https://runkit.com/leonardosnt/java-class-tools-example) (_RunKit:_ you must login with github to be able to fork it) | ||
- [Browser usage example](https://rawgit.com/leonardosnt/java-class-tools/master/examples/browser.html) (List all the methods and fields of a class file) | ||
- [Node usage example](https://repl.it/@leonardosnt/jct-example) (Simple disassembler) | ||
- [Try yourself](https://runkit.com/leonardosnt/java-class-tools-example) (_RunKit:_ you must login with GitHub to be able to fork it) | ||
@@ -19,0 +18,0 @@ Print all method names (node.js) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
14
7.69%582600
-3.44%19
5.56%11469
-2.18%72
-1.37%