Skip to content

Commit 667c819

Browse files
authored
Merge pull request #43 from Tsukuba-Programming-Lab/feature/42-implement-invokespecial-and-invokeinterface
implement invokespecial and invokeinterface
2 parents 3b01928 + 899541a commit 667c819

File tree

12 files changed

+227
-193
lines changed

12 files changed

+227
-193
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"scripts": {
66
"dev": "cd web && npm run dev",
77
"start": "npm run build && cd web && npm run dev",
8+
"build:dev": "clear && wasm-pack build --target web --out-dir web/pkg",
89
"build": "wasm-pack build --target web --out-dir web/pkg",
910
"login": "wasm-pack login",
1011
"pack": "wasm-pack pack web/pkg",

src/classloader/attributes.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use bytes::{Buf, BytesMut};
33
use crate::classloader::constant_pool::{ConstantPoolInfo, utf8_info_as_string};
44
use crate::classloader::java_class_file::{AccessFlag, decode_access_flags};
55

6-
use wasm_rs_dbg::dbg;
7-
86
#[derive(Debug)]
97
pub enum AttributeInfo {
108
ConstantValue(ConstantValueAttribute),

src/classloader/bootstrap_class_loader.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use bytes::{Buf, BytesMut};
55
use web_sys::console::{time, time_end};
66
use crate::classloader::constant_pool::{decode_constant_pool, utf8_info_as_string, ConstantPoolInfo};
77
use crate::classloader::java_class_file::{decode_access_flags, decode_fields, decode_interfaces, decode_methods, decode_this_or_super_class, JavaClassFile};
8-
use wasm_rs_dbg::dbg;
98
use crate::classloader::attributes::decode_attributes;
109

1110
const MAGIC: u32 = 0xCAFEBABE;
@@ -15,7 +14,7 @@ const SUPPORTED_MAJOR_VERSION: f32 = 61.0;
1514
use thiserror::Error;
1615
use crate::classloader::constant_pool::ConstantPoolInfo::Class;
1716
use crate::{error, STORAGE};
18-
use crate::core::method_area::{MethodArea, RuntimeClass};
17+
use crate::core::method_area::{RuntimeClass};
1918
use crate::core::runtime_data_area::RuntimeDataArea;
2019

2120
#[derive(Debug, Error)]
@@ -108,7 +107,7 @@ impl BootstrapClassLoader {
108107
})
109108
}
110109

111-
pub fn load_class(&mut self, class_name: String) -> Option<Rc<Mutex<RuntimeClass>>> {
110+
pub fn load_class(&mut self, class_name: String) -> Option<Rc<RuntimeClass>> {
112111
let clazz = self.rda.lock().unwrap().method_area.lock().unwrap().get_class(&class_name);
113112
return match clazz {
114113
Some(class) => {
@@ -132,7 +131,7 @@ impl BootstrapClassLoader {
132131
match data {
133132
Some(bytes) => {
134133
let class = self.define_class(&class_name, bytes.as_slice()).unwrap();
135-
let runtime_class = Rc::new(Mutex::new(RuntimeClass::new(self, class)));
134+
let runtime_class = Rc::new(RuntimeClass::new(self, class));
136135
self.rda.lock().unwrap().method_area.lock().unwrap().add_class(&class_name, Rc::clone(&runtime_class));
137136
Some(Rc::clone(&runtime_class))
138137
},

src/classloader/constant_pool.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use num_traits::FromPrimitive;
55
use crate::{error};
66

77
use thiserror::Error;
8-
use wasm_rs_dbg::dbg;
98

109
#[derive(Debug, Error)]
1110
enum ErrorType {

src/classloader/java_class_file.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::collections::HashMap;
33
use anyhow::anyhow;
44
use bytes::{Buf, BytesMut};
55
use crate::classloader::constant_pool::{ConstantPoolInfo};
6-
use wasm_rs_dbg::dbg;
76
use crate::classloader::attributes::{AttributeInfo, decode_attributes};
87

98
use thiserror::Error;

src/core.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
#[allow(dead_code)]
12
pub mod method_area;
3+
#[allow(dead_code)]
24
pub mod runtime_data_area;
5+
#[allow(dead_code)]
36
pub mod heap;
7+
#[allow(dead_code)]
48
pub mod stack_area;
59
pub mod native_method_stack;

src/core/heap.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ pub struct RuntimeField {
1515

1616
#[derive(Debug, Clone)]
1717
pub struct JavaInstance {
18-
pub class: Rc<Mutex<RuntimeClass>>,
18+
pub class: Rc<RuntimeClass>,
1919
pub fields: HashMap<String, RuntimeField>,
2020
}
2121

2222
impl JavaInstance {
23-
pub fn new(runtime_object: Rc<Mutex<RuntimeClass>>) -> JavaInstance {
23+
pub fn new(runtime_object: Rc<RuntimeClass>) -> JavaInstance {
2424
let mut fields: HashMap<String, RuntimeField> = HashMap::new();
25-
let mut enumerate_fields = |class: Rc<Mutex<RuntimeClass>>| -> () {
26-
for (key, value) in &class.lock().unwrap().fields {
25+
let mut enumerate_fields = |class: Rc<RuntimeClass>| -> () {
26+
for (key, value) in &class.fields {
2727
let value = value.lock().unwrap();
2828
fields.insert(key.to_string(), RuntimeField {
2929
descriptor: value.descriptor.clone(),
@@ -59,13 +59,13 @@ impl JavaInstance {
5959

6060
#[derive(Debug, Clone)]
6161
pub struct JavaArray {
62-
pub class: Option<Rc<Mutex<RuntimeClass>>>,
62+
pub class: Option<Rc<RuntimeClass>>,
6363
pub length: usize,
6464
pub value: Vec<Value>,
6565
}
6666

6767
impl JavaArray {
68-
pub fn new(class: Rc<Mutex<RuntimeClass>>, length: usize) -> Self {
68+
pub fn new(class: Rc<RuntimeClass>, length: usize) -> Self {
6969
let mut value = Vec::with_capacity(length);
7070
value.fill(Value::new(ValueType::Reference));
7171

src/core/method_area.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use std::collections::HashMap;
2-
use std::marker::PhantomData;
32
use std::rc::Rc;
43
use std::sync::Mutex;
54
use crate::classloader::attributes::AttributeInfo;
65
use crate::classloader::attributes::AttributeInfo::Code;
76
use crate::classloader::bootstrap_class_loader::{BootstrapClassLoader};
87
use crate::classloader::constant_pool::{class_name_as_string, ConstantPoolInfo, utf8_info_as_string};
98
use crate::classloader::java_class_file::{AccessFlag, Descriptor, FieldInfo, JavaClassFile, MethodInfo};
10-
use crate::{error, log};
119

12-
use wasm_rs_dbg::dbg;
1310
use crate::execution::interpreter::Value;
1411
use crate::execution::utils::parse_descriptor;
1512

@@ -42,10 +39,10 @@ pub struct RuntimeClass /*<'a>*/ {
4239
// todo will be removed
4340
pub java_class_file: JavaClassFile,
4441
// pub this_class: Box<Rc<RuntimeClass>>,
45-
pub super_class: Option<Rc<Mutex<RuntimeClass>>>,
46-
pub interfaces: Vec<Rc<Mutex<RuntimeClass>>>,
42+
pub super_class: Option<Rc<RuntimeClass>>,
43+
pub interfaces: Vec<Rc<RuntimeClass>>,
4744
pub name: String,
48-
pub initialized: bool,
45+
pub initialized: Mutex<bool>,
4946
}
5047

5148
impl RuntimeClass {
@@ -81,7 +78,7 @@ impl RuntimeClass {
8178
interfaces,
8279
java_class_file,
8380
name,
84-
initialized: false,
81+
initialized: Mutex::new(false),
8582
}
8683
}
8784

@@ -158,7 +155,7 @@ impl RuntimeClass {
158155
for _ in 0..java_class_file.fields.len() {
159156
let field_info = java_class_file.fields.pop().unwrap();
160157
let name_index = field_info.name_index;
161-
let descriptor_index = field_info.descriptor_index;
158+
// let descriptor_index = field_info.descriptor_index;
162159
let field = Self::build_field(java_class_file, field_info);
163160

164161
let name = utf8_info_as_string!(
@@ -186,11 +183,25 @@ impl RuntimeClass {
186183
static_value: None,
187184
}
188185
}
186+
187+
pub fn lookup_method(class: Rc<RuntimeClass>, name: String) -> Option<Rc<Method>> {
188+
let method = class.methods.get(&name);
189+
190+
match method {
191+
Some(method) => {
192+
Some(Rc::clone(method))
193+
}
194+
_ => {
195+
let Some(super_class) = &class.super_class else { return None };
196+
Self::lookup_method(Rc::clone(super_class), name)
197+
}
198+
}
199+
}
189200
}
190201

191202
#[derive(Debug)]
192203
pub struct MethodArea {
193-
pub indexes: HashMap<String, Rc<Mutex<RuntimeClass>>>,
204+
pub indexes: HashMap<String, Rc<RuntimeClass>>,
194205
}
195206

196207
impl MethodArea {
@@ -200,11 +211,11 @@ impl MethodArea {
200211
}
201212
}
202213

203-
pub fn add_class(&mut self, class_name: &String, class: Rc<Mutex<RuntimeClass>>) {
214+
pub fn add_class(&mut self, class_name: &String, class: Rc<RuntimeClass>) {
204215
self.indexes.insert(class_name.to_string(), class);
205216
}
206217

207-
pub fn get_class(&self, class_name: &String) -> Option<Rc<Mutex<RuntimeClass>>> {
218+
pub fn get_class(&self, class_name: &String) -> Option<Rc<RuntimeClass>> {
208219
match self.indexes.get(class_name) {
209220
Some(value) => Some(Rc::clone(value)),
210221
_ => None

src/core/stack_area.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use std::rc::Rc;
2-
use std::sync::{Mutex, RwLock};
2+
use std::sync::{Mutex};
33
use crate::classloader::attributes::AttributeInfo::{LocalVariableTable, LocalVariableTypeTable};
44
use crate::classloader::attributes::{LocalVariableTableEntry, LocalVariableTypeTableEntry};
55
use crate::core::method_area::{Method, RuntimeClass};
66
use crate::execution::interpreter::{interpret, Value};
7-
use crate::{error, log};
87
use crate::classloader::constant_pool::utf8_info_as_string;
98
use crate::classloader::constant_pool::ConstantPoolInfo;
109

11-
use wasm_rs_dbg::dbg;
1210
use crate::jvm::JVM;
1311

1412
#[derive(Debug)]
@@ -25,15 +23,15 @@ pub struct StackFrame {
2523
}
2624

2725
impl StackFrame {
28-
pub fn new(class: Rc<Mutex<RuntimeClass>>, method: Rc<Method>) -> Self {
26+
pub fn new(class: Rc<RuntimeClass>, method: Rc<Method>) -> Self {
2927
let operand_stack = Vec::with_capacity(method.max_stack as usize);
3028
Self {
3129
local_variables: Self::build_local_variables(class, method),
3230
operand_stack,
3331
}
3432
}
3533

36-
fn build_local_variables(class: Rc<Mutex<RuntimeClass>>, method: Rc<Method>) -> Vec<LocalVariable> {
34+
fn build_local_variables(class: Rc<RuntimeClass>, method: Rc<Method>) -> Vec<LocalVariable> {
3735
let mut result = Vec::with_capacity(method.max_locals as usize);
3836
let descriptor_length = method.descriptor.len() as u16;
3937

@@ -68,19 +66,19 @@ impl StackFrame {
6866
_ => None,
6967
};
7068

71-
result.push(Self::build_local_variable(Rc::clone(&class), local_variable_table_entry, local_variable_type_table_entry, i));
69+
result.push(Self::build_local_variable(Rc::clone(&class), local_variable_table_entry, local_variable_type_table_entry));
7270
}
7371
}
7472

7573
result
7674
}
7775

78-
fn build_local_variable(class: Rc<Mutex<RuntimeClass>>, local_variable_table: Option<&LocalVariableTableEntry>,
79-
local_variable_type_table: Option<&LocalVariableTypeTableEntry>, index: u16) -> LocalVariable {
76+
fn build_local_variable(class: Rc<RuntimeClass>, local_variable_table: Option<&LocalVariableTableEntry>,
77+
local_variable_type_table: Option<&LocalVariableTypeTableEntry>) -> LocalVariable {
8078
return match (local_variable_table, local_variable_type_table) {
8179
(Some(local_variable_table), Some(local_variable_type_table)) => {
82-
let name = utf8_info_as_string!(&class.lock().unwrap().java_class_file.constant_pool, local_variable_table.name_index).to_string();
83-
let type_name = utf8_info_as_string!(&class.lock().unwrap().java_class_file.constant_pool, local_variable_type_table.name_index).to_string();
80+
let name = utf8_info_as_string!(&class.java_class_file.constant_pool, local_variable_table.name_index).to_string();
81+
let type_name = utf8_info_as_string!(&class.java_class_file.constant_pool, local_variable_type_table.name_index).to_string();
8482

8583
Self::_build_local_variable(name, type_name)
8684
}
@@ -123,15 +121,13 @@ impl Thread {
123121
}
124122
}
125123

126-
pub fn invoke_method(&mut self, class: Rc<Mutex<RuntimeClass>>, method_name: &str, args: Vec<Value>) {
127-
let binding = class.lock().unwrap();
128-
let method = Rc::clone(binding.methods.get(method_name).unwrap());
124+
pub fn invoke_method(&mut self, class: Rc<RuntimeClass>, method_name: &str, args: Vec<Value>) {
125+
let method = Rc::clone(class.methods.get(method_name).unwrap());
129126

130127
// let method = class.lock().unwrap().methods.get(method_name).unwrap();
131128
let frame = Rc::new(Mutex::new(StackFrame::new(Rc::clone(&class), Rc::clone(&method))));
132129
self.frame_stack.push(Rc::clone(&frame));
133130

134-
drop(binding); // unlock the class binding
135131
interpret(self, Rc::clone(&frame), Rc::clone(&class), Rc::clone(&method), args);
136132

137133
let popped_frame = self.frame_stack.pop().unwrap();

0 commit comments

Comments
 (0)