Clean up of references and Rcs; better information hiding.
This commit is contained in:
parent
68553a756b
commit
fc9cfcdf7c
@ -59,7 +59,7 @@ mov_usize(
|
|||||||
)
|
)
|
||||||
----
|
----
|
||||||
|
|
||||||
Unlike most other operand types, this operand remains unsigned at runtime.
|
Unlike the other numerical operand types, this operand remains unsigned at runtime.
|
||||||
|
|
||||||
=== Move Double
|
=== Move Double
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ The operand is converted to a `bool` at runtime by the virtual machine.
|
|||||||
|
|
||||||
=== Move Register
|
=== Move Register
|
||||||
|
|
||||||
Moves or copies (see below) the value in one register to another.
|
Copies the value in one register to another.
|
||||||
|
|
||||||
[source]
|
[source]
|
||||||
----
|
----
|
||||||
@ -101,9 +101,6 @@ mov_register(
|
|||||||
)
|
)
|
||||||
----
|
----
|
||||||
|
|
||||||
For `Byte`, `Int`, `Long`, `USize`, `Double`, and `Boolean`, the value is **copied** to the register. For `Object`
|
|
||||||
values, the value is **moved**, meaning that register takes ownership of the referenced object.
|
|
||||||
|
|
||||||
=== Load
|
=== Load
|
||||||
|
|
||||||
Loads the target register with the `DvmValue` inner value stored in the field at `field_index` in the object in the
|
Loads the target register with the `DvmValue` inner value stored in the field at `field_index` in the object in the
|
||||||
|
@ -19,7 +19,12 @@ fn main() {
|
|||||||
|
|
||||||
// std::core::Array
|
// std::core::Array
|
||||||
let array_int = DmInterface::new("std::core::Array", "Array");
|
let array_int = DmInterface::new("std::core::Array", "Array");
|
||||||
let array_int_rc = Rc::new(array_int);
|
array_lib.add_interface(array_int);
|
||||||
|
let array_int_rc = array_lib
|
||||||
|
.interfaces()
|
||||||
|
.iter()
|
||||||
|
.find(|interface| interface.fqn() == "std::core::Array")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// std::core::ArrayImpl
|
// std::core::ArrayImpl
|
||||||
let mut array_impl = DmImplementation::new(
|
let mut array_impl = DmImplementation::new(
|
||||||
@ -58,17 +63,24 @@ fn main() {
|
|||||||
let array_impl_ctor_0_method = DmMethod::new(array_impl_ctor_0_fn, None);
|
let array_impl_ctor_0_method = DmMethod::new(array_impl_ctor_0_fn, None);
|
||||||
array_impl.add_method(array_impl_ctor_0_method);
|
array_impl.add_method(array_impl_ctor_0_method);
|
||||||
|
|
||||||
// Add Array and ArrayImpl to array lib
|
array_lib.add_implementation(array_impl);
|
||||||
array_lib.interfaces.push(array_int_rc.clone());
|
|
||||||
let array_impl_rc = Rc::new(array_impl);
|
|
||||||
array_lib.implementations.push(array_impl_rc.clone());
|
|
||||||
|
|
||||||
// std::core::String
|
// std::core::String
|
||||||
let mut string_lib = DmLib::new("std/core/string");
|
let mut string_lib = DmLib::new("std/core/string");
|
||||||
|
|
||||||
let string_int = DmInterface::new("std::core::String", "String");
|
let string_int = DmInterface::new("std::core::String", "String");
|
||||||
|
string_lib.add_interface(string_int);
|
||||||
|
let string_int_rc = string_lib
|
||||||
|
.interfaces()
|
||||||
|
.iter()
|
||||||
|
.find(|interface| interface.fqn() == "std::core::String")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut string_impl = DmImplementation::new("std::core::StringImpl", "StringImpl", None);
|
let mut string_impl = DmImplementation::new(
|
||||||
|
"std::core::StringImpl",
|
||||||
|
"StringImpl",
|
||||||
|
Some(string_int_rc.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
let bytes_field = DmField::new("bytes", DmType::Object);
|
let bytes_field = DmField::new("bytes", DmType::Object);
|
||||||
string_impl.add_field(bytes_field);
|
string_impl.add_field(bytes_field);
|
||||||
@ -92,14 +104,11 @@ fn main() {
|
|||||||
|
|
||||||
string_impl.add_method(string_ctor_0_method);
|
string_impl.add_method(string_ctor_0_method);
|
||||||
|
|
||||||
string_lib.interfaces.push(Rc::new(string_int));
|
string_lib.add_implementation(string_impl);
|
||||||
string_lib.implementations.push(Rc::new(string_impl));
|
|
||||||
|
|
||||||
// greeting lib
|
// greeting lib
|
||||||
let mut greeting_lib = DmLib::new("greeting");
|
let mut greeting_lib = DmLib::new("greeting");
|
||||||
greeting_lib
|
greeting_lib.add_constant(DmConstant::String("Hello, World!".to_string()));
|
||||||
.constants
|
|
||||||
.push(DmConstant::String("Hello, Jeanna!".to_string()));
|
|
||||||
|
|
||||||
let mut main_byte_code = Vec::new();
|
let mut main_byte_code = Vec::new();
|
||||||
|
|
||||||
@ -141,7 +150,7 @@ fn main() {
|
|||||||
|
|
||||||
let main_dm_fn = DmFn::new("main", "main", main_byte_code, 7, None);
|
let main_dm_fn = DmFn::new("main", "main", main_byte_code, 7, None);
|
||||||
|
|
||||||
greeting_lib.functions.push(Rc::new(main_dm_fn));
|
greeting_lib.add_function(main_dm_fn);
|
||||||
|
|
||||||
let mut state = DvmState::new();
|
let mut state = DvmState::new();
|
||||||
let mut context = DvmContext::new();
|
let mut context = DvmContext::new();
|
||||||
@ -150,7 +159,7 @@ fn main() {
|
|||||||
Rc::new(string_lib),
|
Rc::new(string_lib),
|
||||||
Rc::new(array_lib),
|
Rc::new(array_lib),
|
||||||
]);
|
]);
|
||||||
context.load_platform_fns(&init_platform_functions());
|
context.load_platform_fns(init_platform_functions());
|
||||||
|
|
||||||
let main_fn = context.fn_by_fqn("main").unwrap();
|
let main_fn = context.fn_by_fqn("main").unwrap();
|
||||||
call_fn(&mut state, &context, &main_fn, vec![]);
|
call_fn(&mut state, &context, &main_fn, vec![]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::vm::object::DvmObject;
|
use crate::vm::object::DvmObject;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum DvmValue {
|
pub enum DvmValue {
|
||||||
Byte(u8),
|
Byte(u8),
|
||||||
Int(i32),
|
Int(i32),
|
||||||
@ -15,6 +15,10 @@ pub enum DvmValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DvmValue {
|
impl DvmValue {
|
||||||
|
pub fn from_object(object: DvmObject) -> Self {
|
||||||
|
DvmValue::Object(Rc::new(object))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expect_long(&self) -> i64 {
|
pub fn expect_long(&self) -> i64 {
|
||||||
if let DvmValue::Long(l) = self {
|
if let DvmValue::Long(l) = self {
|
||||||
*l
|
*l
|
||||||
|
@ -7,11 +7,11 @@ use crate::vm::object_type::{DmFn, DmImplementation, DmInterface};
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct DmLib {
|
pub struct DmLib {
|
||||||
pub name: String,
|
name: String,
|
||||||
pub constants: Vec<DmConstant>,
|
constants: Vec<DmConstant>,
|
||||||
pub interfaces: Vec<Rc<DmInterface>>,
|
interfaces: Vec<Rc<DmInterface>>,
|
||||||
pub implementations: Vec<Rc<DmImplementation>>,
|
implementations: Vec<Rc<DmImplementation>>,
|
||||||
pub functions: Vec<Rc<DmFn>>,
|
functions: Vec<Rc<DmFn>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DmLib {
|
impl DmLib {
|
||||||
@ -24,6 +24,42 @@ impl DmLib {
|
|||||||
functions: Vec::new(),
|
functions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn constants(&self) -> &Vec<DmConstant> {
|
||||||
|
&self.constants
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_constant(&mut self, constant: DmConstant) {
|
||||||
|
self.constants.push(constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interfaces(&self) -> &Vec<Rc<DmInterface>> {
|
||||||
|
&self.interfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_interface(&mut self, interface: DmInterface) {
|
||||||
|
self.interfaces.push(Rc::new(interface));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn implementations(&self) -> &Vec<Rc<DmImplementation>> {
|
||||||
|
&self.implementations
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_implementation(&mut self, implementation: DmImplementation) {
|
||||||
|
self.implementations.push(Rc::new(implementation));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn functions(&self) -> &Vec<Rc<DmFn>> {
|
||||||
|
&self.functions
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_function(&mut self, function: DmFn) {
|
||||||
|
self.functions.push(Rc::new(function));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -34,70 +34,66 @@ struct CallFrameInfo {
|
|||||||
|
|
||||||
pub struct DvmContext {
|
pub struct DvmContext {
|
||||||
libs: Vec<Rc<DmLib>>,
|
libs: Vec<Rc<DmLib>>,
|
||||||
functions: HashMap<String, Rc<DmFn>>,
|
function_cache: HashMap<String, Rc<DmFn>>,
|
||||||
platform_functions: HashMap<String, Rc<PlatformFunction>>,
|
platform_functions: HashMap<String, PlatformFunction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DvmContext {
|
impl DvmContext {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
DvmContext {
|
DvmContext {
|
||||||
libs: Vec::new(),
|
libs: Vec::new(),
|
||||||
functions: HashMap::new(),
|
function_cache: HashMap::new(),
|
||||||
platform_functions: HashMap::new(),
|
platform_functions: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_libs(&mut self, libs: Vec<Rc<DmLib>>) {
|
pub fn load_libs(&mut self, libs: Vec<Rc<DmLib>>) {
|
||||||
for lib in libs {
|
for lib in libs {
|
||||||
self.libs.push(lib.clone());
|
for lib_fn in lib.functions() {
|
||||||
for lib_fn in &lib.functions {
|
self.function_cache
|
||||||
self.functions
|
|
||||||
.insert(lib_fn.fqn().to_string(), lib_fn.clone());
|
.insert(lib_fn.fqn().to_string(), lib_fn.clone());
|
||||||
}
|
}
|
||||||
for interface_function in lib
|
for interface_function in lib
|
||||||
.interfaces
|
.interfaces()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|interface| interface.get_functions())
|
.flat_map(|interface| interface.functions())
|
||||||
{
|
{
|
||||||
self.functions.insert(
|
self.function_cache.insert(
|
||||||
interface_function.fqn().to_string(),
|
interface_function.fqn().to_string(),
|
||||||
interface_function.clone(),
|
interface_function.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for implementation_function in lib
|
for implementation_function in lib
|
||||||
.implementations
|
.implementations()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|implementation| implementation.functions())
|
.flat_map(|implementation| implementation.functions())
|
||||||
{
|
{
|
||||||
self.functions.insert(
|
self.function_cache.insert(
|
||||||
implementation_function.fqn().to_string(),
|
implementation_function.fqn().to_string(),
|
||||||
implementation_function.clone(),
|
implementation_function.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for method in lib
|
for method in lib
|
||||||
.implementations
|
.implementations()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|implementation| implementation.methods())
|
.flat_map(|implementation| implementation.methods())
|
||||||
{
|
{
|
||||||
self.functions
|
self.function_cache
|
||||||
.insert(method.dm_fn().fqn().to_string(), method.dm_fn().clone());
|
.insert(method.dm_fn().fqn().to_string(), method.dm_fn());
|
||||||
}
|
}
|
||||||
|
self.libs.push(lib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_platform_fns(&mut self, platform_fns: &HashMap<String, PlatformFunction>) {
|
pub fn load_platform_fns(&mut self, platform_fns: HashMap<String, PlatformFunction>) {
|
||||||
for (fqn, platform_fn) in platform_fns {
|
platform_fns.iter().for_each(|(fqn, platform_function)| {
|
||||||
self.platform_functions
|
self.platform_functions
|
||||||
.insert(fqn.to_string(), Rc::new(*platform_fn));
|
.insert(fqn.to_string(), *platform_function);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_by_fqn(&self, fqn: &str) -> Option<Rc<DmFn>> {
|
pub fn fn_by_fqn(&self, fqn: &str) -> Option<Rc<DmFn>> {
|
||||||
self.functions.get(fqn).cloned()
|
self.function_cache.get(fqn).cloned()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn platform_fn_by_fqn(&self, fqn: &str) -> Option<Rc<PlatformFunction>> {
|
|
||||||
self.platform_functions.get(fqn).cloned()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,8 +277,9 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
|
|||||||
MOV_REGISTER => {
|
MOV_REGISTER => {
|
||||||
let target_register = next_8!(iter, usize);
|
let target_register = next_8!(iter, usize);
|
||||||
let source_register = next_8!(iter, usize);
|
let source_register = next_8!(iter, usize);
|
||||||
let source_value = state.registers.get(source_register).unwrap();
|
let source_value =
|
||||||
state.registers[target_register] = source_value.clone();
|
std::mem::replace(&mut state.registers[source_register], DvmValue::Uninit);
|
||||||
|
state.registers[target_register] = source_value;
|
||||||
}
|
}
|
||||||
LOAD => {
|
LOAD => {
|
||||||
let target_register = next_8!(iter, usize);
|
let target_register = next_8!(iter, usize);
|
||||||
@ -321,25 +318,24 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
|
|||||||
.libs
|
.libs
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|lib| {
|
.find_map(|lib| {
|
||||||
lib.implementations
|
lib.implementations()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|implementation| implementation.fqn() == impl_name)
|
.find(|implementation| implementation.fqn() == impl_name)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
dvm_panic!(&format!("Implementation not found: {}", impl_name), state)
|
dvm_panic!(&format!("Implementation not found: {}", impl_name), state)
|
||||||
});
|
})
|
||||||
|
.clone();
|
||||||
|
|
||||||
let dm_alloc_object = DvmObject::new(implementation.clone());
|
let dm_alloc_object = DvmObject::new(implementation);
|
||||||
state.registers[target_register] = DvmValue::Object(Rc::new(dm_alloc_object));
|
state.registers[target_register] = DvmValue::from_object(dm_alloc_object);
|
||||||
}
|
}
|
||||||
DEALLOC => {
|
DEALLOC => {
|
||||||
let target_register = next_8!(iter, usize);
|
let target_register = next_8!(iter, usize);
|
||||||
let dvm_object = state
|
let target_object =
|
||||||
.registers
|
std::mem::replace(&mut state.registers[target_register], DvmValue::Uninit)
|
||||||
.get(target_register)
|
|
||||||
.unwrap()
|
|
||||||
.expect_object();
|
.expect_object();
|
||||||
drop(dvm_object); // explicit
|
drop(target_object); // explicit
|
||||||
state.registers[target_register] = DvmValue::Uninit;
|
state.registers[target_register] = DvmValue::Uninit;
|
||||||
}
|
}
|
||||||
MOV_CONST => {
|
MOV_CONST => {
|
||||||
@ -350,13 +346,13 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
|
|||||||
let const_id = next_32_le!(iter, usize);
|
let const_id = next_32_le!(iter, usize);
|
||||||
|
|
||||||
// Get constant
|
// Get constant
|
||||||
let Some(lib) = context.libs.iter().find(|lib| lib.name == lib_name) else {
|
let Some(lib) = context.libs.iter().find(|lib| lib.name() == lib_name) else {
|
||||||
dvm_panic!(
|
dvm_panic!(
|
||||||
&format!("Could not find lib with name: {}", lib_name),
|
&format!("Could not find lib with name: {}", lib_name),
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let constant = lib.constants.get(const_id).unwrap();
|
let constant = lib.constants().get(const_id).unwrap();
|
||||||
let DmConstant::String(s) = constant;
|
let DmConstant::String(s) = constant;
|
||||||
let pointer = s.as_ptr();
|
let pointer = s.as_ptr();
|
||||||
|
|
||||||
@ -404,11 +400,7 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
|
|||||||
args.push(value.clone());
|
args.push(value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let platform_function = context
|
let platform_function = context.platform_functions.get(&symbol_name).unwrap();
|
||||||
.platform_functions
|
|
||||||
.get(&symbol_name)
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
state
|
state
|
||||||
.call_stack
|
.call_stack
|
||||||
.push(CallFrame::PlatformCall(CallFrameInfo { fqn: symbol_name }));
|
.push(CallFrame::PlatformCall(CallFrameInfo { fqn: symbol_name }));
|
||||||
@ -427,7 +419,7 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
|
|||||||
args.push(value.clone());
|
args.push(value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let dm_fn = context.functions.get(&symbol_name).unwrap();
|
let dm_fn = context.function_cache.get(&symbol_name).unwrap();
|
||||||
let call_result = call_fn(state, context, dm_fn, args);
|
let call_result = call_fn(state, context, dm_fn, args);
|
||||||
state.registers[return_register] = call_result;
|
state.registers[return_register] = call_result;
|
||||||
}
|
}
|
||||||
@ -481,14 +473,11 @@ mod run_code_tests {
|
|||||||
|
|
||||||
macro_rules! assert_register {
|
macro_rules! assert_register {
|
||||||
( $expected: expr, $state: expr, $register_number: expr ) => {
|
( $expected: expr, $state: expr, $register_number: expr ) => {
|
||||||
assert_eq!(
|
assert_eq!($expected, $state.registers.remove($register_number));
|
||||||
$expected,
|
|
||||||
$state.registers.get($register_number).unwrap().clone()
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(number_of_registers: usize) -> (DvmState, DvmContext) {
|
fn setup<'a>(number_of_registers: usize) -> (DvmState, DvmContext) {
|
||||||
let mut state = DvmState::new();
|
let mut state = DvmState::new();
|
||||||
state
|
state
|
||||||
.registers
|
.registers
|
||||||
@ -543,13 +532,17 @@ mod run_code_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn load_object() {
|
fn load_object() {
|
||||||
let dummy_impl = impl_with_object_field();
|
let dummy_impl = impl_with_object_field();
|
||||||
let dummy_impl_rc = Rc::new(dummy_impl);
|
|
||||||
let mut dummy_lib = DmLib::new("dummy");
|
let mut dummy_lib = DmLib::new("dummy");
|
||||||
dummy_lib.implementations.push(dummy_impl_rc.clone());
|
dummy_lib.add_implementation(dummy_impl);
|
||||||
|
let dummy_impl_ref = dummy_lib
|
||||||
|
.implementations()
|
||||||
|
.iter()
|
||||||
|
.find(|implementation| implementation.fqn() == "dummy")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
add_alloc(&mut code, 0, &dummy_impl_rc.fqn());
|
add_alloc(&mut code, 0, dummy_impl_ref.fqn());
|
||||||
add_alloc(&mut code, 1, &dummy_impl_rc.fqn());
|
add_alloc(&mut code, 1, dummy_impl_ref.fqn());
|
||||||
add_store(&mut code, 0, 0, 1);
|
add_store(&mut code, 0, 0, 1);
|
||||||
add_load(&mut code, 2, 0, 0);
|
add_load(&mut code, 2, 0, 0);
|
||||||
|
|
||||||
|
@ -3,12 +3,6 @@ use crate::vm::object::DvmObject;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum DmObjectType {
|
|
||||||
Interface(DmInterface),
|
|
||||||
Implementation(DmImplementation),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Eq)]
|
#[derive(Debug, Eq)]
|
||||||
pub struct DmFn {
|
pub struct DmFn {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
@ -92,7 +86,7 @@ pub struct DmInterface {
|
|||||||
fqn: String,
|
fqn: String,
|
||||||
short_name: String,
|
short_name: String,
|
||||||
functions: Vec<Rc<DmFn>>,
|
functions: Vec<Rc<DmFn>>,
|
||||||
virtual_methods: Vec<Rc<DmVirtualMethod>>,
|
virtual_methods: Vec<DmVirtualMethod>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for DmInterface {
|
impl PartialEq for DmInterface {
|
||||||
@ -123,28 +117,16 @@ impl DmInterface {
|
|||||||
self.functions.push(Rc::new(dm_fn));
|
self.functions.push(Rc::new(dm_fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_functions(&self) -> Vec<Rc<DmFn>> {
|
pub fn functions(&self) -> &Vec<Rc<DmFn>> {
|
||||||
self.functions.clone()
|
&self.functions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_method(&mut self, dm_virtual_method: DmVirtualMethod) {
|
pub fn add_method(&mut self, dm_virtual_method: DmVirtualMethod) {
|
||||||
self.virtual_methods.push(Rc::new(dm_virtual_method));
|
self.virtual_methods.push(dm_virtual_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_method(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DmMethod>> {
|
pub fn virtual_methods(&self) -> &Vec<DmVirtualMethod> {
|
||||||
if self
|
&self.virtual_methods
|
||||||
.virtual_methods
|
|
||||||
.iter()
|
|
||||||
.find(|&dm_fn| dm_fn.fqn == name)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
return self_object.implementation().find_method(name, self_object);
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_virtual_methods(&self) -> Vec<Rc<DmVirtualMethod>> {
|
|
||||||
self.virtual_methods.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,25 +199,29 @@ impl DmImplementation {
|
|||||||
self.interface.clone()
|
self.interface.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn functions(&self) -> Vec<Rc<DmFn>> {
|
pub fn functions(&self) -> &Vec<Rc<DmFn>> {
|
||||||
self.functions.clone()
|
&self.functions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn methods(&self) -> Vec<Rc<DmMethod>> {
|
pub fn add_function(&mut self, dm_fn: DmFn) {
|
||||||
self.methods.clone()
|
self.functions.push(Rc::new(dm_fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn methods(&self) -> &Vec<Rc<DmMethod>> {
|
||||||
|
&self.methods
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_method(&mut self, dm_method: DmMethod) {
|
pub fn add_method(&mut self, dm_method: DmMethod) {
|
||||||
self.methods.push(Rc::new(dm_method));
|
self.methods.push(Rc::new(dm_method));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_method(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DmMethod>> {
|
pub fn find_method(&self, name: &str, self_object: &DvmObject) -> Option<&DmMethod> {
|
||||||
for method in &self.methods {
|
for method in &self.methods {
|
||||||
if method.dm_fn.fqn == name {
|
if method.dm_fn.fqn == name {
|
||||||
return Some(method.clone());
|
return Some(method);
|
||||||
} else if let Some(implements) = &method.implements {
|
} else if let Some(implements) = &method.implements {
|
||||||
if implements.fqn == name {
|
if implements.fqn == name {
|
||||||
return Some(method.clone());
|
return Some(method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user