From 144951a9e9e6c87866245f2bdeebf0ebedaa0e38 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Wed, 18 Feb 2015 17:38:30 -0800 Subject: Add lambda experimental dalvik opcodes * Add new -X/--experimental flag to [dis]assemble opcodes not in art yet * Add new opcodes liberate-variable, box-lambda, unbox-lambda, capture-variable, create-lambda, invoke-lambda * Add support for encoding 25x instructions * Adds LambdaTest to check new opcodes assemble/disassemble properly TODO: invoke-lambda-range Change-Id: I5c8bcbfa8b6cb9a13ef2017fce2d1b7fda6e11c3 --- smali/src/main/antlr/smaliParser.g | 42 +++++++++++- smali/src/main/antlr/smaliTreeWalker.g | 79 +++++++++++++++++++++- .../src/main/java/org/jf/smali/SmaliTestUtils.java | 14 +++- smali/src/main/java/org/jf/smali/main.java | 29 ++++++-- smali/src/main/jflex/smaliLexer.jflex | 19 +++++- .../test/resources/LexerTest/InstructionTest.smali | 6 ++ .../resources/LexerTest/InstructionTest.tokens | 6 ++ 7 files changed, 180 insertions(+), 15 deletions(-) (limited to 'smali') diff --git a/smali/src/main/antlr/smaliParser.g b/smali/src/main/antlr/smaliParser.g index d057b4a4..6d07452c 100644 --- a/smali/src/main/antlr/smaliParser.g +++ b/smali/src/main/antlr/smaliParser.g @@ -86,6 +86,8 @@ tokens { INSTRUCTION_FORMAT21c_FIELD_ODEX; INSTRUCTION_FORMAT21c_STRING; INSTRUCTION_FORMAT21c_TYPE; + INSTRUCTION_FORMAT21c_LAMBDA; + INSTRUCTION_FORMAT21c_METHOD; INSTRUCTION_FORMAT21ih; INSTRUCTION_FORMAT21lh; INSTRUCTION_FORMAT21s; @@ -94,12 +96,14 @@ tokens { INSTRUCTION_FORMAT22c_FIELD; INSTRUCTION_FORMAT22c_FIELD_ODEX; INSTRUCTION_FORMAT22c_TYPE; + INSTRUCTION_FORMAT22c_STRING; INSTRUCTION_FORMAT22cs_FIELD; INSTRUCTION_FORMAT22s; INSTRUCTION_FORMAT22s_OR_ID; INSTRUCTION_FORMAT22t; INSTRUCTION_FORMAT22x; INSTRUCTION_FORMAT23x; + INSTRUCTION_FORMAT25x; INSTRUCTION_FORMAT30t; INSTRUCTION_FORMAT31c; INSTRUCTION_FORMAT31i; @@ -209,6 +213,8 @@ tokens { I_STATEMENT_FORMAT21c_TYPE; I_STATEMENT_FORMAT21c_FIELD; I_STATEMENT_FORMAT21c_STRING; + I_STATEMENT_FORMAT21c_LAMBDA; + I_STATEMENT_FORMAT21c_METHOD; I_STATEMENT_FORMAT21ih; I_STATEMENT_FORMAT21lh; I_STATEMENT_FORMAT21s; @@ -216,10 +222,12 @@ tokens { I_STATEMENT_FORMAT22b; I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT22c_TYPE; + I_STATEMENT_FORMAT22c_STRING; I_STATEMENT_FORMAT22s; I_STATEMENT_FORMAT22t; I_STATEMENT_FORMAT22x; I_STATEMENT_FORMAT23x; + I_STATEMENT_FORMAT25x; I_STATEMENT_FORMAT30t; I_STATEMENT_FORMAT31c; I_STATEMENT_FORMAT31i; @@ -252,7 +260,7 @@ import org.jf.dexlib2.Opcodes; private boolean verboseErrors = false; private boolean allowOdex = false; private int apiLevel = 15; - private Opcodes opcodes = new Opcodes(apiLevel); + private Opcodes opcodes = new Opcodes(apiLevel, false); public void setVerboseErrors(boolean verboseErrors) { this.verboseErrors = verboseErrors; @@ -262,8 +270,8 @@ import org.jf.dexlib2.Opcodes; this.allowOdex = allowOdex; } - public void setApiLevel(int apiLevel) { - this.opcodes = new Opcodes(apiLevel); + public void setApiLevel(int apiLevel, boolean experimental) { + this.opcodes = new Opcodes(apiLevel, experimental); this.apiLevel = apiLevel; } @@ -561,14 +569,18 @@ simple_name | INSTRUCTION_FORMAT21c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_FIELD_ODEX] | INSTRUCTION_FORMAT21c_STRING -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_STRING] | INSTRUCTION_FORMAT21c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_TYPE] + | INSTRUCTION_FORMAT21c_LAMBDA -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_LAMBDA] + | INSTRUCTION_FORMAT21c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_METHOD] | INSTRUCTION_FORMAT21t -> SIMPLE_NAME[$INSTRUCTION_FORMAT21t] | INSTRUCTION_FORMAT22c_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD] | INSTRUCTION_FORMAT22c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD_ODEX] | INSTRUCTION_FORMAT22c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_TYPE] + | INSTRUCTION_FORMAT22c_STRING -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_STRING] | INSTRUCTION_FORMAT22cs_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22cs_FIELD] | INSTRUCTION_FORMAT22s_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT22s_OR_ID] | INSTRUCTION_FORMAT22t -> SIMPLE_NAME[$INSTRUCTION_FORMAT22t] | INSTRUCTION_FORMAT23x -> SIMPLE_NAME[$INSTRUCTION_FORMAT23x] + | INSTRUCTION_FORMAT25x -> SIMPLE_NAME[$INSTRUCTION_FORMAT25x] | INSTRUCTION_FORMAT31i_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT31i_OR_ID] | INSTRUCTION_FORMAT31t -> SIMPLE_NAME[$INSTRUCTION_FORMAT31t] | INSTRUCTION_FORMAT35c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD] @@ -806,6 +818,8 @@ instruction | insn_format21c_field_odex | insn_format21c_string | insn_format21c_type + | insn_format21c_lambda + | insn_format21c_method | insn_format21ih | insn_format21lh | insn_format21s @@ -814,11 +828,13 @@ instruction | insn_format22c_field | insn_format22c_field_odex | insn_format22c_type + | insn_format22c_string | insn_format22cs_field | insn_format22s | insn_format22t | insn_format22x | insn_format23x + | insn_format25x | insn_format30t | insn_format31c | insn_format31i @@ -912,6 +928,16 @@ insn_format21c_type INSTRUCTION_FORMAT21c_TYPE REGISTER COMMA nonvoid_type_descriptor -> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER nonvoid_type_descriptor); +insn_format21c_lambda + : //e.g. capture-variable v1, "foobar" + INSTRUCTION_FORMAT21c_LAMBDA REGISTER COMMA STRING_LITERAL + -> ^(I_STATEMENT_FORMAT21c_LAMBDA[$start, "I_STATEMENT_FORMAT21c_LAMBDA"] INSTRUCTION_FORMAT21c_LAMBDA REGISTER STRING_LITERAL); + +insn_format21c_method + : //e.g. create-lambda v1, java/io/PrintStream/print(Ljava/lang/Stream;)V + INSTRUCTION_FORMAT21c_METHOD REGISTER COMMA method_reference + -> ^(I_STATEMENT_FORMAT21c_METHOD[$start, "I_STATEMENT_FORMAT21c_METHOD"] INSTRUCTION_FORMAT21c_METHOD REGISTER method_reference); + insn_format21ih : //e.g. const/high16 v1, 1234 INSTRUCTION_FORMAT21ih REGISTER COMMA fixed_32bit_literal @@ -957,6 +983,11 @@ insn_format22c_type INSTRUCTION_FORMAT22c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor -> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor); +insn_format22c_string + : //e.g. liberate-variable v0, v1, "baz" + INSTRUCTION_FORMAT22c_STRING REGISTER COMMA REGISTER COMMA STRING_LITERAL + -> ^(I_STATEMENT_FORMAT22c_STRING[$start, "I_STATEMENT_FORMAT22c_STRING"] INSTRUCTION_FORMAT22c_STRING REGISTER REGISTER STRING_LITERAL); + insn_format22cs_field : //e.g. iget-quick v0, v1, field@0xc INSTRUCTION_FORMAT22cs_FIELD REGISTER COMMA REGISTER COMMA FIELD_OFFSET @@ -984,6 +1015,11 @@ insn_format23x INSTRUCTION_FORMAT23x REGISTER COMMA REGISTER COMMA REGISTER -> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER); +insn_format25x + : //e.g. invoke-lambda vClosure, {vA, vB, vC, vD} -- up to 4 parameters + the closure. + INSTRUCTION_FORMAT25x REGISTER COMMA OPEN_BRACE register_list CLOSE_BRACE + -> ^(I_STATEMENT_FORMAT25x[$start, "I_STATEMENT_FORMAT25x"] INSTRUCTION_FORMAT25x REGISTER register_list); + insn_format30t : //e.g. goto/32 endloop: INSTRUCTION_FORMAT30t label_ref diff --git a/smali/src/main/antlr/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g index f49f10ef..d319b2ca 100644 --- a/smali/src/main/antlr/smaliTreeWalker.g +++ b/smali/src/main/antlr/smaliTreeWalker.g @@ -77,15 +77,15 @@ import java.util.*; public String classType; private boolean verboseErrors = false; private int apiLevel = 15; - private Opcodes opcodes = new Opcodes(apiLevel); + private Opcodes opcodes = new Opcodes(apiLevel, false); private DexBuilder dexBuilder; public void setDexBuilder(DexBuilder dexBuilder) { this.dexBuilder = dexBuilder; } - public void setApiLevel(int apiLevel) { - this.opcodes = new Opcodes(apiLevel); + public void setApiLevel(int apiLevel, boolean experimental) { + this.opcodes = new Opcodes(apiLevel, experimental); this.apiLevel = apiLevel; } @@ -674,6 +674,22 @@ register_list returns[byte[\] registers, byte registerCount] $registers[$registerCount++] = parseRegister_nibble($REGISTER.text); })*); +register_list4 returns[byte[\] registers, byte registerCount] + @init + { + $registers = new byte[4]; + $registerCount = 0; + } + : ^(I_REGISTER_LIST + (REGISTER + { + if ($registerCount == 4) { + throw new SemanticException(input, $I_REGISTER_LIST, "A list4 of registers can only have a maximum of 4 " + + "registers. Use the /range alternate opcode instead."); + } + $registers[$registerCount++] = parseRegister_nibble($REGISTER.text); + })*); + register_range returns[int startRegister, int endRegister] : ^(I_REGISTER_RANGE (startReg=REGISTER endReg=REGISTER?)?) { @@ -726,6 +742,8 @@ instruction | insn_format21c_field | insn_format21c_string | insn_format21c_type + | insn_format21c_lambda + | insn_format21c_method | insn_format21ih | insn_format21lh | insn_format21s @@ -733,10 +751,12 @@ instruction | insn_format22b | insn_format22c_field | insn_format22c_type + | insn_format22c_string | insn_format22s | insn_format22t | insn_format22x | insn_format23x + | insn_format25x | insn_format30t | insn_format31c | insn_format31i @@ -861,6 +881,30 @@ insn_format21c_type dexBuilder.internTypeReference($nonvoid_type_descriptor.type))); }; +insn_format21c_lambda + : //e.g. capture-variable v1, "foobar" + ^(I_STATEMENT_FORMAT21c_LAMBDA INSTRUCTION_FORMAT21c_LAMBDA REGISTER string_literal) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT21c_LAMBDA.text); + short regA = parseRegister_byte($REGISTER.text); + + $method::methodBuilder.addInstruction(new BuilderInstruction21c(opcode, regA, + dexBuilder.internStringReference($string_literal.value))); + }; + +insn_format21c_method + : //e.g. create-lambda v1, java/io/PrintStream/print(Ljava/lang/Stream;)V + ^(I_STATEMENT_FORMAT21c_METHOD INSTRUCTION_FORMAT21c_METHOD REGISTER method_reference) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT21c_METHOD.text); + short regA = parseRegister_byte($REGISTER.text); + + ImmutableMethodReference methodReference = $method_reference.methodReference; + + $method::methodBuilder.addInstruction(new BuilderInstruction21c(opcode, regA, + dexBuilder.internMethodReference(methodReference))); + }; + insn_format21ih : //e.g. const/high16 v1, 1234 ^(I_STATEMENT_FORMAT21ih INSTRUCTION_FORMAT21ih REGISTER fixed_32bit_literal) @@ -947,6 +991,18 @@ insn_format22c_type dexBuilder.internTypeReference($nonvoid_type_descriptor.type))); }; +insn_format22c_string + : //e.g. liberate-variable v0, v1, "baz" + ^(I_STATEMENT_FORMAT22c_STRING INSTRUCTION_FORMAT22c_STRING registerA=REGISTER registerB=REGISTER string_literal) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT22c_STRING.text); + byte regA = parseRegister_nibble($registerA.text); + byte regB = parseRegister_nibble($registerB.text); + + $method::methodBuilder.addInstruction(new BuilderInstruction22c(opcode, regA, regB, + dexBuilder.internStringReference($string_literal.value))); + }; + insn_format22s : //e.g. add-int/lit16 v0, v1, 12345 ^(I_STATEMENT_FORMAT22s INSTRUCTION_FORMAT22s registerA=REGISTER registerB=REGISTER short_integral_literal) @@ -994,6 +1050,23 @@ insn_format23x $method::methodBuilder.addInstruction(new BuilderInstruction23x(opcode, regA, regB, regC)); }; +insn_format25x + : //e.g. invoke-lambda vClosure, {vD, vE, vF, vG} -- up to 4 parameters + the closure. + ^(I_STATEMENT_FORMAT25x INSTRUCTION_FORMAT25x REGISTER register_list4) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT25x.text); + + byte closureRegister = parseRegister_nibble($REGISTER.text); + + //this depends on the fact that register_list4 returns a byte[4] + byte[] registers = $register_list4.registers; + int parameterRegisterCount = $register_list4.registerCount; // don't count closure register + + $method::methodBuilder.addInstruction(new BuilderInstruction25x(opcode, + parameterRegisterCount, closureRegister, registers[0], registers[1], + registers[2], registers[3])); + }; + insn_format30t : //e.g. goto/32 endloop: ^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t label_ref) diff --git a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java index 9fd73473..26de0089 100644 --- a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java +++ b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java @@ -48,10 +48,16 @@ import java.io.Reader; import java.io.StringReader; public class SmaliTestUtils { + public static ClassDef compileSmali(String smaliText) throws RecognitionException, IOException { + return compileSmali(smaliText, 15, false); + } + + public static ClassDef compileSmali(String smaliText, int apiLevel, boolean experimental) + throws RecognitionException, IOException { CommonTokenStream tokens; LexerErrorInterface lexer; - DexBuilder dexBuilder = DexBuilder.makeDexBuilder(15); + DexBuilder dexBuilder = DexBuilder.makeDexBuilder(apiLevel); Reader reader = new StringReader(smaliText); @@ -61,7 +67,7 @@ public class SmaliTestUtils { smaliParser parser = new smaliParser(tokens); parser.setVerboseErrors(true); parser.setAllowOdex(false); - parser.setApiLevel(15); + parser.setApiLevel(apiLevel, experimental); smaliParser.smali_file_return result = parser.smali_file(); @@ -75,6 +81,7 @@ public class SmaliTestUtils { treeStream.setTokenStream(tokens); smaliTreeWalker dexGen = new smaliTreeWalker(treeStream); + dexGen.setApiLevel(apiLevel, experimental); dexGen.setVerboseErrors(true); dexGen.setDexBuilder(dexBuilder); dexGen.smali_file(); @@ -87,7 +94,8 @@ public class SmaliTestUtils { dexBuilder.writeTo(dataStore); - DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15), dataStore.getData()); + DexBackedDexFile dexFile = new DexBackedDexFile( + new Opcodes(apiLevel, experimental), dataStore.getData()); return Iterables.getFirst(dexFile.getClasses(), null); } diff --git a/smali/src/main/java/org/jf/smali/main.java b/smali/src/main/java/org/jf/smali/main.java index c6095bf3..31f65a88 100644 --- a/smali/src/main/java/org/jf/smali/main.java +++ b/smali/src/main/java/org/jf/smali/main.java @@ -34,6 +34,7 @@ import org.antlr.runtime.Token; import org.antlr.runtime.TokenSource; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; +import org.antlr.runtime.tree.TreeNodeStream; import org.apache.commons.cli.*; import org.jf.dexlib2.writer.builder.DexBuilder; import org.jf.dexlib2.writer.io.FileDataStore; @@ -110,6 +111,7 @@ public class main { boolean allowOdex = false; boolean verboseErrors = false; boolean printTokens = false; + boolean experimental = false; int apiLevel = 15; @@ -142,6 +144,9 @@ public class main { case 'x': allowOdex = true; break; + case 'X': + experimental = true; + break; case 'a': apiLevel = Integer.parseInt(commandLine.getOptionValue("a")); break; @@ -198,11 +203,12 @@ public class main { final boolean finalPrintTokens = printTokens; final boolean finalAllowOdex = allowOdex; final int finalApiLevel = apiLevel; + final boolean finalExperimental = experimental; for (final File file: filesToProcess) { tasks.add(executor.submit(new Callable() { @Override public Boolean call() throws Exception { return assembleSmaliFile(file, dexBuilder, finalVerboseErrors, finalPrintTokens, - finalAllowOdex, finalApiLevel); + finalAllowOdex, finalApiLevel, finalExperimental); } })); } @@ -252,7 +258,8 @@ public class main { } private static boolean assembleSmaliFile(File smaliFile, DexBuilder dexBuilder, boolean verboseErrors, - boolean printTokens, boolean allowOdex, int apiLevel) + boolean printTokens, boolean allowOdex, int apiLevel, + boolean experimental) throws Exception { CommonTokenStream tokens; @@ -267,7 +274,7 @@ public class main { if (printTokens) { tokens.getTokens(); - + for (int i=0; i' + return newToken(INSTRUCTION_FORMAT21c_LAMBDA); + } + + "create-lambda" { // e.g. 'create-lambda vClosure, ' + return newToken(INSTRUCTION_FORMAT21c_METHOD); + } + "const/high16" { return newToken(INSTRUCTION_FORMAT21ih); } @@ -492,10 +500,13 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor} return newToken(INSTRUCTION_FORMAT22c_FIELD_ODEX); } - "instance-of" | "new-array" { + "instance-of" | "new-array" | "unbox-lambda" { return newToken(INSTRUCTION_FORMAT22c_TYPE); } + "liberate-variable" { + return newToken(INSTRUCTION_FORMAT22c_STRING); + } "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" { return newToken(INSTRUCTION_FORMAT22cs_FIELD); } @@ -513,7 +524,7 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor} return newToken(INSTRUCTION_FORMAT22t); } - "move/from16" | "move-wide/from16" | "move-object/from16" { + "move/from16" | "move-wide/from16" | "move-object/from16" | "box-lambda" { return newToken(INSTRUCTION_FORMAT22x); } @@ -527,6 +538,10 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor} return newToken(INSTRUCTION_FORMAT23x); } + "invoke-lambda" { // e.g. invoke-lambda vClosure, {vD, vE, vF, vG} -- at most 4 params + return newToken(INSTRUCTION_FORMAT25x); + } + "goto/32" { return newToken(INSTRUCTION_FORMAT30t); } diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali index 2247adc0..f6dcbb1e 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.smali +++ b/smali/src/test/resources/LexerTest/InstructionTest.smali @@ -84,6 +84,8 @@ const-string check-cast new-instance const-class +capture-variable +create-lambda const/high16 const-wide/high16 const/16 @@ -122,6 +124,8 @@ iput-wide-volatile iput-object-volatile instance-of new-array +unbox-lambda +liberate-variable iget-quick iget-wide-quick iget-object-quick @@ -144,6 +148,7 @@ if-le move/from16 move-wide/from16 move-object/from16 +box-lambda cmpl-float cmpg-float cmpl-double @@ -194,6 +199,7 @@ add-double sub-double mul-double div-double +invoke-lambda goto/32 const-string/jumbo const diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens index a5574ab4..fb5503b5 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.tokens +++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens @@ -84,6 +84,8 @@ INSTRUCTION_FORMAT21c_STRING("const-string") INSTRUCTION_FORMAT21c_TYPE("check-cast") INSTRUCTION_FORMAT21c_TYPE("new-instance") INSTRUCTION_FORMAT21c_TYPE("const-class") +INSTRUCTION_FORMAT21c_LAMBDA("capture-variable") +INSTRUCTION_FORMAT21c_METHOD("create-lambda") INSTRUCTION_FORMAT21ih("const/high16") INSTRUCTION_FORMAT21lh("const-wide/high16") INSTRUCTION_FORMAT21s("const/16") @@ -122,6 +124,8 @@ INSTRUCTION_FORMAT22c_FIELD_ODEX("iput-wide-volatile") INSTRUCTION_FORMAT22c_FIELD_ODEX("iput-object-volatile") INSTRUCTION_FORMAT22c_TYPE("instance-of") INSTRUCTION_FORMAT22c_TYPE("new-array") +INSTRUCTION_FORMAT22c_TYPE("unbox-lambda") +INSTRUCTION_FORMAT22c_STRING("liberate-variable") INSTRUCTION_FORMAT22cs_FIELD("iget-quick") INSTRUCTION_FORMAT22cs_FIELD("iget-wide-quick") INSTRUCTION_FORMAT22cs_FIELD("iget-object-quick") @@ -144,6 +148,7 @@ INSTRUCTION_FORMAT22t("if-le") INSTRUCTION_FORMAT22x("move/from16") INSTRUCTION_FORMAT22x("move-wide/from16") INSTRUCTION_FORMAT22x("move-object/from16") +INSTRUCTION_FORMAT22x("box-lambda") INSTRUCTION_FORMAT23x("cmpl-float") INSTRUCTION_FORMAT23x("cmpg-float") INSTRUCTION_FORMAT23x("cmpl-double") @@ -194,6 +199,7 @@ INSTRUCTION_FORMAT23x("add-double") INSTRUCTION_FORMAT23x("sub-double") INSTRUCTION_FORMAT23x("mul-double") INSTRUCTION_FORMAT23x("div-double") +INSTRUCTION_FORMAT25x("invoke-lambda") INSTRUCTION_FORMAT30t("goto/32") INSTRUCTION_FORMAT31c("const-string/jumbo") INSTRUCTION_FORMAT31i_OR_ID("const") -- cgit v1.2.3