From 0e785d55560685155c3b104e81f3a786a34a7f08 Mon Sep 17 00:00:00 2001 From: pacemaker <2318702434@qq.com> Date: Thu, 28 Dec 2023 19:47:39 +0800 Subject: [PATCH] =?UTF-8?q?switch=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86TABLESWITCH=E5=92=8CLOOKUPSWITCH?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E6=8C=87=E4=BB=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jvm/instruction/InstructionFactory.java | 4 +-- .../jvm/instruction/control/LOOKUPSWITCH.java | 34 +++++++++++++++++-- .../jvm/instruction/control/TABLESWITCH.java | 24 +++++++++++-- src/test/java/haidnor/jvm/test/TestJVM.java | 8 +++++ .../jvm/test/demo/demo_switch_lookup.java | 23 +++++++++++++ .../jvm/test/demo/demo_switch_table.java | 23 +++++++++++++ 6 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 src/test/java/haidnor/jvm/test/demo/demo_switch_lookup.java create mode 100644 src/test/java/haidnor/jvm/test/demo/demo_switch_table.java diff --git a/src/main/java/haidnor/jvm/instruction/InstructionFactory.java b/src/main/java/haidnor/jvm/instruction/InstructionFactory.java index befe732..5ea1aa1 100644 --- a/src/main/java/haidnor/jvm/instruction/InstructionFactory.java +++ b/src/main/java/haidnor/jvm/instruction/InstructionFactory.java @@ -526,10 +526,10 @@ public abstract class InstructionFactory { return new RET(codeStream); } case Const.TABLESWITCH -> { - return new TABLESWITCH(codeStream); // TODO + return new TABLESWITCH(codeStream); } case Const.LOOKUPSWITCH -> { - return new LOOKUPSWITCH(codeStream); // TODO + return new LOOKUPSWITCH(codeStream); } case Const.IRETURN -> { return new IRETURN(codeStream); diff --git a/src/main/java/haidnor/jvm/instruction/control/LOOKUPSWITCH.java b/src/main/java/haidnor/jvm/instruction/control/LOOKUPSWITCH.java index f839940..ddfc7e1 100644 --- a/src/main/java/haidnor/jvm/instruction/control/LOOKUPSWITCH.java +++ b/src/main/java/haidnor/jvm/instruction/control/LOOKUPSWITCH.java @@ -1,19 +1,47 @@ package haidnor.jvm.instruction.control; + import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.core.CodeStream; - +import lombok.extern.slf4j.Slf4j; +import java.util.LinkedHashMap; +import java.util.Map; +@Slf4j public class LOOKUPSWITCH extends Instruction { + private final int count;//索引数量 + private final int jump_default;//默认跳转 + private final Map map;//映射表 + + public LOOKUPSWITCH(CodeStream codeStream) { super(codeStream); - throw new UnsupportedOperationException("LOOKUPSWITCH"); + this.jump_default = codeStream.readInt(this); + + this.count = codeStream.readInt(this); + + this.map = new LinkedHashMap<>(); + for(int i=0;i map;//映射表 + public TABLESWITCH(CodeStream codeStream) { super(codeStream); - throw new UnsupportedOperationException("TABLESWITCH"); + this.jump_default = codeStream.readInt(this); + this.low_case_value = codeStream.readInt(this); + this.high_case_value = codeStream.readInt(this); + this.map = new LinkedHashMap<>(); + for(int i=low_case_value;i<=high_case_value;i++) + { + map.put(i,codeStream.readInt(this)); + //创建映射表 + } } @Override public void execute(Frame frame) { - throw new UnsupportedOperationException("TABLESWITCH"); + + int value = frame.popInt();//取出index + Integer offSet = map.getOrDefault(value, jump_default);//得到跳转值 + super.setOffSet(offSet); } } diff --git a/src/test/java/haidnor/jvm/test/TestJVM.java b/src/test/java/haidnor/jvm/test/TestJVM.java index d14a5dc..c01160c 100644 --- a/src/test/java/haidnor/jvm/test/TestJVM.java +++ b/src/test/java/haidnor/jvm/test/TestJVM.java @@ -158,6 +158,14 @@ public class TestJVM { public void test_Array() throws Exception { HaidnorJVM.testRun(Array.class); } + @Test + public void test_Switch_table() throws Exception { + HaidnorJVM.testRun(demo_switch_table.class); + } + @Test + public void test_Switch_lookup() throws Exception { + HaidnorJVM.testRun(demo_switch_lookup.class); + } @Test public void test_() throws Exception { diff --git a/src/test/java/haidnor/jvm/test/demo/demo_switch_lookup.java b/src/test/java/haidnor/jvm/test/demo/demo_switch_lookup.java new file mode 100644 index 0000000..1b85343 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_switch_lookup.java @@ -0,0 +1,23 @@ +package haidnor.jvm.test.demo; + +public class demo_switch_lookup { + public static void main(String[] args) { + //LOOKUPSWITCH的demo + int i = 1; + switch (i) { + case 1: + System.out.println("1"); + break; + case 2: + System.out.println("2"); + break; + case 10: + System.out.println("10"); + break; + default: + System.out.println("default"); + break; + } + + } +} diff --git a/src/test/java/haidnor/jvm/test/demo/demo_switch_table.java b/src/test/java/haidnor/jvm/test/demo/demo_switch_table.java new file mode 100644 index 0000000..3c6f60d --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_switch_table.java @@ -0,0 +1,23 @@ +package haidnor.jvm.test.demo; + +public class demo_switch_table { + public static void main(String[] args) { + int i = 3; + switch (i) { + case 1: + System.out.println("1"); + break; + case 2: + System.out.println("2"); + break; + case 3: + System.out.println("3"); + break; + case 4: + System.out.println("4"); + break; + default: + System.out.println("0"); + } + } +}