blob: be665055e3caa907e3c89ddfeb5d280d83547e4d [file] [log] [blame]
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;
}