Skip to content

Commit f92d35b

Browse files
committed
jvm: Enforce max stack, add more string tests
1 parent 91db18f commit f92d35b

File tree

7 files changed

+35
-23
lines changed

7 files changed

+35
-23
lines changed

example/Rot13.java renamed to example/StringTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package jvmtest;
22

3-
class Rot13 {
4-
public static void main(String[] args) {
5-
System.out.println(rot13("Gb trg gb gur bgure fvqr!"));
3+
class StringTest {
4+
public static String reverseString(String s) {
5+
return new StringBuilder(s).reverse().toString();
66
}
77

88
public static String rot13(String str) {
@@ -23,4 +23,4 @@ private static char rot13(char ch) {
2323
}
2424
return ch;
2525
}
26-
}
26+
}

pyjvm/Machine.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ def execute_code(self, frame):
353353
inst = Inst(code[frame.ip])
354354
#print(frame.ip, inst)
355355

356-
#if len(frame.stack) > frame.max_stack + 1:
357-
# print("MAX STACK")
356+
if len(frame.stack) > frame.max_stack + 1:
357+
print("MAX STACK")
358+
break
358359

359360
if inst in OPCODES:
360361
OPCODES[inst](frame)
@@ -582,8 +583,9 @@ def execute_code(self, frame):
582583
cl = self.class_files[name]
583584
if cl.canHandleMethod(nat.name, nat.desc):
584585
ret = cl.handleMethod(nat.name, nat.desc, frame)
585-
if not nat.desc.endswith('V'):
586-
frame.push(ret)
586+
else:
587+
frame.stack.pop()
588+
587589
elif inst == Inst.INVOKESTATIC:
588590
index = read_unsigned_short(frame)
589591

pyjvm/jstdlib/JavaClass.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def python_initialize(self, *args):
1717
pass
1818

1919
def __repr__(self):
20-
return '<{} - {}>'.format(self.name(), self.instance_fields)
20+
return f'<{self.name()} - {self.instance_fields}>'
2121

2222
def get_field(self, name):
2323
return self.instance_fields[name]
@@ -32,4 +32,4 @@ def handleMethod(self, name, desc, frame):
3232
pass
3333

3434
def handleStatic(self, name, desc, frame):
35-
pass
35+
pass

pyjvm/jstdlib/Rng.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ def canHandleMethod(self, name, desc):
1111

1212
def handleMethod(self, name, desc, frame, code, machine, ip):
1313
if name == 'generate':
14-
frame.stack.append(random.randint(0, 100))
14+
frame.stack.append(random.randint(0, 100))

pyjvm/jstdlib/String.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ def handleMethod(self, name, desc, frame):
1212
super().handleMethod(name, desc, frame)
1313
if name == 'length':
1414
val = frame.pop()
15-
#frame.push(len(val))
1615
return len(val)
1716
elif name == 'charAt':
1817
index = frame.pop()
1918
s = frame.pop()
20-
#frame.push(s[index])
21-
return s[index]
19+
return s[index]

pyjvm/jstdlib/StringBuilder.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ def python_initialize(self, *args):
99
self.string = ''
1010

1111
def canHandleMethod(self, name, desc):
12-
return name in ['append', 'toString']
12+
if name == '<init>' and desc == '(Ljava/lang/String;)V':
13+
return True
14+
15+
return name in ['append', 'toString', 'reverse']
1316

1417
def handleMethod(self, name, desc, frame):
1518
super().handleMethod(name, desc, frame)
@@ -18,9 +21,14 @@ def handleMethod(self, name, desc, frame):
1821
v1 = frame.stack.pop()
1922
v1.string += v2
2023
return v1
21-
#frame.stack.append(v1)
2224
elif name == 'toString':
2325
v1 = frame.stack.pop()
24-
frame.stack.pop()
25-
#frame.stack.append(v1.string)
26-
return v1.string
26+
return v1.string
27+
elif name == 'reverse':
28+
v1 = frame.stack.pop()
29+
v1.string = v1.string[::-1]
30+
return v1
31+
elif name == '<init>' and desc == '(Ljava/lang/String;)V':
32+
s = frame.stack.pop()
33+
v1 = frame.stack.pop()
34+
v1.string = s

run_unittest.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,20 @@ def test_recursive_fibonacci(self):
4949
self.assertEqual(self.jvm
5050
.call_function('jvmtest/IntegerTest/recursiveFibonacci', 7), 13)
5151

52-
class Rot13Test(unittest.TestCase):
52+
class StringTest(unittest.TestCase):
5353
def setUp(self):
5454
self.jvm = Machine()
5555
load_stdlib_classes(self.jvm)
56-
self.jvm.load_class_file('example/Rot13.class')
56+
self.jvm.load_class_file('example/StringTest.class')
5757

5858
def test_rot13_hello_world(self):
5959
self.assertEqual(self.jvm
60-
.call_function('jvmtest/Rot13/rot13', 'Hello World!')
61-
, 'Uryyb Jbeyq!')
60+
.call_function('jvmtest/StringTest/rot13', 'Hello World!')
61+
, 'Uryyb Jbeyq!')
62+
63+
def test_reverse_string(self):
64+
r = self.jvm.call_function('jvmtest/StringTest/reverseString', 'Test message!')
65+
self.assertEqual(r, '!egassem tseT')
6266

6367
class InstanceTest(unittest.TestCase):
6468
def setUp(self):

0 commit comments

Comments
 (0)