| use std::prelude::v1::*; |
| use std::any::Any; |
| use std::cmp::Ordering; |
| use errors; |
| use executor::{ExecutorImpl}; |
| use object_pool::ObjectPool; |
| use value::{Value, ValueContext}; |
| |
| /// A heap-allocated object. |
| /// |
| /// This is the core abstraction in the Hexagon VM type system. |
| /// After creating, an object must be pinned to the object pool |
| /// for use in the virtual environment. |
| /// |
| /// If any initialization is required before the object is pinned |
| /// to object pool, it should be done in the `initialize` method, |
| /// which takes a mutable reference to the object pool and makes |
| /// it possible to do preparations e.g. creating built-in fields. |
| pub trait Object: Send { |
| fn finalize(&self, _pool: &mut ObjectPool) {} |
| |
| // before allocating on the object pool... |
| fn initialize(&mut self, _pool: &mut ObjectPool) {} |
| |
| fn call(&self, _executor: &mut ExecutorImpl) -> Value { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Not callable"))); |
| } |
| fn call_field(&self, field_name: &str, executor: &mut ExecutorImpl) -> Value { |
| let field = self.must_get_field(executor.get_object_pool(), field_name); |
| let obj = ValueContext::new(&field, executor.get_object_pool()).as_object(); |
| obj.call(executor) |
| } |
| fn get_field(&self, _pool: &ObjectPool, _name: &str) -> Option<Value> { |
| None |
| } |
| fn set_field(&self, _name: &str, _value_ref: Value) { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Cannot set field"))); |
| } |
| fn must_get_field(&self, pool: &ObjectPool, name: &str) -> Value { |
| match self.get_field(pool, name) { |
| Some(v) => v, |
| None => panic!(errors::VMError::from(errors::FieldNotFoundError::from_field_name(name))) |
| } |
| } |
| fn has_const_field(&self, _pool: &ObjectPool, _name: &str) -> bool { |
| false |
| } |
| fn compare(&self, _other: &ValueContext) -> Option<Ordering> { |
| None |
| } |
| fn test_eq(&self, _other: &ValueContext) -> bool { |
| false |
| } |
| fn typename(&self) -> &str { |
| "object" |
| } |
| fn to_i64(&self) -> i64 { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Cannot cast to i64"))); |
| } |
| fn to_f64(&self) -> f64 { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Cannot cast to f64"))); |
| } |
| fn to_str(&self) -> &str { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Cannot cast to str"))); |
| } |
| fn to_string(&self) -> String { |
| self.to_str().to_string() |
| } |
| fn to_bool(&self) -> bool { |
| panic!(errors::VMError::from(errors::RuntimeError::new("Cannot cast to bool"))); |
| } |
| fn get_children(&self) -> Vec<usize>; |
| fn as_any(&self) -> &Any; |
| fn as_any_mut(&mut self) -> &mut Any; |
| } |