mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 16:58:09 +00:00
P-code parsing of NumberContext
This commit is contained in:
@@ -36,6 +36,10 @@ public class NumberContext {
|
||||
public static final int USE_DOUBLE = 2;
|
||||
public static final int USE_INT = 3;
|
||||
public static final int USE_UINT = 4;
|
||||
|
||||
private static String[] usageNames = new String[]{"Number", "decimal", "double", "int", "uint"};
|
||||
|
||||
private static String[] roundingNames = new String[] {"CEILING", "UP", "HALF_UP", "HALF_EVEN", "HALF_DOWN", "DOWN", "FLOOR"};
|
||||
|
||||
/**
|
||||
* Usage of the number.
|
||||
@@ -72,6 +76,9 @@ public class NumberContext {
|
||||
this.usage = param & 7;
|
||||
this.rounding = (param >> 3) & 7;
|
||||
this.precision = param >> 6;
|
||||
if ((usage == USE_NUMBER || usage == USE_DECIMAL) && precision == 0) {
|
||||
precision = 34;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +87,7 @@ public class NumberContext {
|
||||
* @param usage Usage
|
||||
*/
|
||||
public void setUsage(int usage) {
|
||||
if (usage > 6 || usage < 0) {
|
||||
if (usage > usageNames.length || usage < 0) {
|
||||
throw new IllegalArgumentException("Invalid usage value :" + usage);
|
||||
}
|
||||
this.usage = usage;
|
||||
@@ -116,6 +123,26 @@ public class NumberContext {
|
||||
this.precision = precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rounding of the number.
|
||||
*
|
||||
* @param rounding Rounding
|
||||
*/
|
||||
public void setRounding(int rounding) {
|
||||
if (rounding > roundingNames.length || rounding < 0) {
|
||||
throw new IllegalArgumentException("Invalid rounding value :" + rounding);
|
||||
}
|
||||
this.rounding = rounding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rounding of the number
|
||||
* @return Rounding
|
||||
*/
|
||||
public int getRounding() {
|
||||
return rounding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the number context to a parameter.
|
||||
*
|
||||
@@ -131,4 +158,36 @@ public class NumberContext {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String usageToName(int usage) {
|
||||
if (usage > usageNames.length || usage < 0) {
|
||||
throw new IllegalArgumentException("Invalid usage value :" + usage);
|
||||
}
|
||||
return usageNames[usage];
|
||||
}
|
||||
|
||||
public static String roundingToName(int rounding) {
|
||||
if (rounding > roundingNames.length || rounding < 0) {
|
||||
throw new IllegalArgumentException("Invalid rounding value :" + rounding);
|
||||
}
|
||||
return roundingNames[rounding];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("NumberContext");
|
||||
sb.append("(");
|
||||
sb.append(usageToName(usage));
|
||||
if (usage == USE_NUMBER || usage == USE_DECIMAL) {
|
||||
sb.append(",");
|
||||
sb.append(roundingToName(rounding));
|
||||
if (precision < 34) {
|
||||
sb.append(",");
|
||||
sb.append(precision);
|
||||
}
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.ABCOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.NumberContext;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
@@ -459,6 +460,11 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_NUMBER_CONTEXT:
|
||||
NumberContext nc = new NumberContext(operands[i]);
|
||||
s.append(" ");
|
||||
s.append(nc.toString());
|
||||
break;
|
||||
case AVM2Code.DAT_OFFSET:
|
||||
s.append(" ");
|
||||
s.append("ofs");
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.pcode;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.NumberContext;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.DeobfuscatePopIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
@@ -466,6 +467,77 @@ public class ASM3Parser {
|
||||
return parseSlotConst(abc, lexer, constants, tsc);
|
||||
}
|
||||
|
||||
|
||||
private static int parseNumberContext(Flasm3Lexer lexer) throws AVM2ParseException, IOException {
|
||||
ParsedSymbol s = lexer.lex();
|
||||
expected(s, ParsedSymbol.TYPE_KEYWORD_NUMBERCONTEXT, "NumberContext", lexer.yyline());
|
||||
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
|
||||
s = lexer.lex();
|
||||
int usage;
|
||||
switch (s.type) {
|
||||
case ParsedSymbol.TYPE_KEYWORD_NUMBER:
|
||||
usage = NumberContext.USE_NUMBER;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_DECIMAL:
|
||||
usage = NumberContext.USE_DECIMAL;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_DOUBLE:
|
||||
usage = NumberContext.USE_DOUBLE;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_INT:
|
||||
usage = NumberContext.USE_INT;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_UINT:
|
||||
usage = NumberContext.USE_UINT;
|
||||
break;
|
||||
default:
|
||||
throw new AVM2ParseException("Usage expected - one of: Number, decimal, double, int or uint", lexer.yyline());
|
||||
}
|
||||
int rounding = NumberContext.ROUND_HALF_UP;
|
||||
int precision = 34;
|
||||
if (usage == NumberContext.USE_NUMBER || usage == NumberContext.USE_DECIMAL) {
|
||||
expected(ParsedSymbol.TYPE_COMMA, ",", lexer);
|
||||
s = lexer.lex();
|
||||
switch (s.type) {
|
||||
case ParsedSymbol.TYPE_KEYWORD_CEILING:
|
||||
rounding = NumberContext.ROUND_CEILING;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_UP:
|
||||
rounding = NumberContext.ROUND_UP;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_HALF_UP:
|
||||
rounding = NumberContext.ROUND_HALF_UP;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_HALF_EVEN:
|
||||
rounding = NumberContext.ROUND_HALF_EVEN;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_HALF_DOWN:
|
||||
rounding = NumberContext.ROUND_HALF_DOWN;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_DOWN:
|
||||
rounding = NumberContext.ROUND_DOWN;
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_FLOOR:
|
||||
rounding = NumberContext.ROUND_FLOOR;
|
||||
break;
|
||||
default:
|
||||
throw new AVM2ParseException("Rounding expected - one of: CEILING, UP, HALF_UP, HALF_EVEN, HALF_DOWN, DOWN, FLOOR", lexer.yyline());
|
||||
}
|
||||
s = lexer.lex();
|
||||
if (s.type == ParsedSymbol.TYPE_COMMA) {
|
||||
s = lexer.lex();
|
||||
precision = (int) getUInteger(s, lexer.yyline(), false);
|
||||
if (precision > 34) {
|
||||
throw new AVM2ParseException("Precision must not exceed 34", lexer.yyline());
|
||||
}
|
||||
} else {
|
||||
lexer.pushback(s);
|
||||
}
|
||||
}
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
return new NumberContext(usage, precision, rounding).toParam();
|
||||
}
|
||||
|
||||
private static int parseNamespaceSet(AVM2ConstantPool constants, Flasm3Lexer lexer) throws AVM2ParseException, IOException {
|
||||
List<Integer> namespaceList = new ArrayList<>();
|
||||
ParsedSymbol s = lexer.lex();
|
||||
@@ -1310,6 +1382,10 @@ public class ASM3Parser {
|
||||
operandsList.add(did);
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_NUMBER_CONTEXT:
|
||||
lexer.pushback(parsedOperand);
|
||||
operandsList.add(parseNumberContext(lexer));
|
||||
break;
|
||||
case AVM2Code.DAT_FLOAT_INDEX:
|
||||
if (parsedOperand.type == ParsedSymbol.TYPE_KEYWORD_NULL) {
|
||||
operandsList.add(0);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -519,6 +519,61 @@ public class ParsedSymbol {
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_PROTECTEDNS_BLOCK = 97;
|
||||
|
||||
/**
|
||||
* Type: Keyword Number
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_NUMBER = 98;
|
||||
|
||||
/**
|
||||
* Type: Keyword int
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_INT = 99;
|
||||
|
||||
/**
|
||||
* Type: Keyword uint
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_UINT = 100;
|
||||
|
||||
/**
|
||||
* Type: Keyword NumberContext
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_NUMBERCONTEXT = 101;
|
||||
|
||||
/**
|
||||
* Type: Keyword CEILING
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_CEILING = 102;
|
||||
|
||||
/**
|
||||
* Type: Keyword UP
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_UP = 103;
|
||||
|
||||
/**
|
||||
* Type: Keyword HALF_UP
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_HALF_UP = 104;
|
||||
|
||||
/**
|
||||
* Type: Keyword HALF_EVEN
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_HALF_EVEN = 105;
|
||||
|
||||
/**
|
||||
* Type: Keyword HALF_DOWN
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_HALF_DOWN = 106;
|
||||
|
||||
/**
|
||||
* Type: Keyword DOWN
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_DOWN = 107;
|
||||
|
||||
/**
|
||||
* Type: Keyword FLOOR
|
||||
*/
|
||||
public static final int TYPE_KEYWORD_FLOOR = 108;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pos Position
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user