Skip to content

Commit

Permalink
feat(tvm):extend the opcode args num
Browse files Browse the repository at this point in the history
feat(tvm):reduce repeated opcode
  • Loading branch information
limuy2022 committed Apr 12, 2024
1 parent d59d74b commit 122cedb
Show file tree
Hide file tree
Showing 11 changed files with 524 additions and 456 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 17 additions & 18 deletions libcore/src/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::{cmp::max, fmt};
use std::{fmt::Display, usize};
use std::fmt::Display;

#[derive(Clone)]
pub struct FuncStorage {
Expand Down Expand Up @@ -112,18 +112,8 @@ pub enum Opcode {
MoveBool,
MoveStr,
// Store a local var
StoreLocalObj,
StoreLocalInt,
StoreLocalFloat,
StoreLocalChar,
StoreLocalBool,
StoreLocalStr,
StoreGlobalObj,
StoreGlobalInt,
StoreGlobalFloat,
StoreGlobalChar,
StoreGlobalBool,
StoreGlobalStr,
StoreLocal,
StoreGlobal,
// Do Nothing
Empty,
// a = -a
Expand All @@ -149,7 +139,6 @@ pub enum Opcode {
PopDataStr,
PopDataChar,
PopDataBool,
ImportNativeModule,
}

impl Display for Opcode {
Expand Down Expand Up @@ -180,19 +169,29 @@ pub const ARG_WRONG: usize = usize::MAX;
#[derive(Debug, PartialEq, Clone)]
pub struct Inst {
pub opcode: Opcode,
pub operand: usize,
pub operand: (usize, usize),
}

impl Inst {
pub fn new(opcode: Opcode, operand: usize) -> Self {
Self { opcode, operand }
pub fn new_single(opcode: Opcode, operand: usize) -> Self {
Self {
opcode,
operand: (operand, ARG_WRONG),
}
}

pub fn new_double(opcode: Opcode, operand1: usize, operand2: usize) -> Self {
Self {
opcode,
operand: (operand1, operand2),
}
}
}

impl Display for Inst {
#[cfg(not(tarpaulin_include))]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.opcode, self.operand)
write!(f, "{} {} {}", self.opcode, self.operand.0, self.operand.1)
}
}

Expand Down
57 changes: 48 additions & 9 deletions libcore/src/dynadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ pub fn get_max_stack_sz() -> usize {
*T.get_or_init(|| 1024 * 1024 * 2 / size_of::<Byte>())
}

pub fn get_trcobj_sz() -> usize {
static T: OnceLock<usize> = OnceLock::new();
*T.get_or_init(size_of::<*mut dyn crate::types::TrcObj>)
}

#[derive(Default)]
pub struct DynaData {
pub gc: GcMgr,
Expand Down Expand Up @@ -89,6 +84,23 @@ impl DynaData {
unsafe { *(self.run_stack.as_ptr().byte_offset(self.stack_ptr as isize) as *const T) }
}

/// Pop n bytes of stack
pub fn pop_n_bytes_data(&mut self, n: usize) -> *mut Byte {
debug_assert!(self.stack_ptr >= n);
self.stack_ptr -= n;
unsafe {
let ret = self
.run_stack
.as_mut_ptr()
.byte_offset(self.stack_ptr as isize);
#[cfg(debug_assertions)]
{
self.type_used.pop().unwrap();
}
ret
}
}

/// Returns the top data of the data stack.
///
/// # Panics
Expand Down Expand Up @@ -117,15 +129,42 @@ impl DynaData {
}
}

pub fn set_var<T: 'static>(&mut self, addr: usize, data: T) {
/// Sets the var of this [`DynaData`].
///
/// # Safety
/// make sure your addr is valid, or it will panic
/// .
pub unsafe fn set_var<T: 'static>(&mut self, addr: usize, data: T) {
unsafe {
*(self.var_store.as_mut_ptr().byte_offset(addr as isize) as *mut T) = data;
(self.get_var_addr_mut(addr) as *mut T).write(data);
}
}

pub fn get_var<T: Copy + 'static>(&self, addr: usize) -> T {
/// Sets the var of this [`DynaData`].
///
/// # Safety
/// make sure your addr is valid, or it will panic
/// .
pub unsafe fn get_var<T: Copy + 'static>(&self, addr: usize) -> T {
debug_assert!(addr < self.var_used);
unsafe { *(self.var_store.as_ptr().byte_offset(addr as isize) as *const T) }
unsafe { *(self.get_var_addr(addr) as *const T) }
}

/// Sets the var of this [`DynaData`].
///
/// # Safety
/// make sure your addr and src are valid, or it will panic
/// .
pub unsafe fn write_to_val(&mut self, addr: usize, src: *mut Byte, n: usize) {
unsafe { self.get_var_addr_mut(addr).copy_from(src, n) }
}

fn get_var_addr(&self, addr: usize) -> *const Byte {
unsafe { self.var_store.as_ptr().byte_offset(addr as isize) }
}

fn get_var_addr_mut(&mut self, addr: usize) -> *mut Byte {
unsafe { self.var_store.as_mut_ptr().byte_offset(addr as isize) }
}

pub fn alloc_var_space(&mut self, need_sz: usize) -> *mut Byte {
Expand Down
36 changes: 36 additions & 0 deletions libcore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,40 @@ pub use types::*;
pub const GET_LIB_FUNC_NAME: &str = "get_lib";
pub const GET_STORAGE_FUNC_NAME: &str = "get_storage";

#[macro_export]
macro_rules! intsz {
() => {
std::mem::size_of::<$crate::TrcIntInternal>()
};
}
#[macro_export]
macro_rules! floatsz {
() => {
std::mem::size_of::<$crate::TrcFloatInternal>()
};
}
#[macro_export]
macro_rules! charsz {
() => {
std::mem::size_of::<$crate::TrcCharInternal>()
};
}
#[macro_export]
macro_rules! strsz {
() => {
std::mem::size_of::<$crate::TrcStrInternal>()
};
}
#[macro_export]
macro_rules! boolsz {
() => {
std::mem::size_of::<bool>()
};
}
#[macro_export]
macro_rules! objsz {
() => {
std::mem::size_of::<*mut dyn $crate::TrcObj>()
};
}
rust_i18n::i18n!("locales");
50 changes: 17 additions & 33 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,22 +238,22 @@ impl<'a> AstBuilder<'a> {
self.lex_until(RightBigBrace)?;
self.add_bycode(Opcode::Jump, condit_id);
let opcode_after_while = self.staticdata.get_next_opcode_id();
self.staticdata.inst[jump_false_id].operand = opcode_after_while;
self.staticdata.inst[jump_false_id].operand.0 = opcode_after_while;
let mut break_record = vec![];
swap(
&mut break_record,
&mut self.self_scope.borrow_mut().for_break,
);
for i in break_record {
self.staticdata.inst[i].operand = opcode_after_while;
self.staticdata.inst[i].operand.0 = opcode_after_while;
}
let mut continue_record = vec![];
swap(
&mut continue_record,
&mut self.self_scope.borrow_mut().for_continue,
);
for i in continue_record {
self.staticdata.inst[i].operand = condit_id;
self.staticdata.inst[i].operand.0 = condit_id;
}
swap(
&mut prev_loop_state,
Expand Down Expand Up @@ -310,23 +310,23 @@ impl<'a> AstBuilder<'a> {
// 跳转到条件判断语句
self.add_bycode(Opcode::Jump, conid_id);
let next_opcode_after_for = self.staticdata.get_next_opcode_id();
self.staticdata.inst[jump_false_id].operand = next_opcode_after_for;
self.staticdata.inst[jump_false_id].operand.0 = next_opcode_after_for;
// 开始处理所有的break
let mut break_record = vec![];
swap(
&mut break_record,
&mut self.self_scope.borrow_mut().for_break,
);
for i in break_record {
self.staticdata.inst[i].operand = next_opcode_after_for;
self.staticdata.inst[i].operand.0 = next_opcode_after_for;
}
let mut continue_record = vec![];
swap(
&mut continue_record,
&mut self.self_scope.borrow_mut().for_continue,
);
for i in continue_record {
self.staticdata.inst[i].operand = opcode_goto;
self.staticdata.inst[i].operand.0 = opcode_goto;
}
// 重置循环状态
swap(
Expand Down Expand Up @@ -684,7 +684,7 @@ impl<'a> AstBuilder<'a> {
self.add_bycode(Opcode::Jump, ARG_WRONG);
add_expr_addr(self.staticdata.get_last_opcode_id());
for i in &jump_into_case {
self.staticdata.inst[*i].operand = self.staticdata.get_next_opcode_id();
self.staticdata.inst[*i].operand.0 = self.staticdata.get_next_opcode_id();
}
self.get_token_checked(TokenType::LeftBigBrace)?;
self.lex_until(RightBigBrace)?;
Expand All @@ -708,7 +708,7 @@ impl<'a> AstBuilder<'a> {
loop {
for i in &jump_condit_save {
let t = self.staticdata.get_next_opcode_id();
self.staticdata.inst[*i].operand = t;
self.staticdata.inst[*i].operand.0 = t;
}
jump_condit_save.clear();
let t = self.token_lexer.next_token()?;
Expand All @@ -726,7 +726,7 @@ impl<'a> AstBuilder<'a> {
)?;
}
for i in jump_case_final {
self.staticdata.inst[i].operand = self.staticdata.get_next_opcode_id();
self.staticdata.inst[i].operand.0 = self.staticdata.get_next_opcode_id();
}
}
}
Expand Down Expand Up @@ -994,28 +994,12 @@ impl<'a> AstBuilder<'a> {

/// 生成修改变量的指令
fn modify_var(&mut self, varty: TyIdxTy, var_addr: usize, is_global: bool) {
self.add_bycode(
if !is_global {
match self.convert_id_to_vm_ty(varty) {
VmStackType::Int => Opcode::StoreLocalInt,
VmStackType::Float => Opcode::StoreLocalFloat,
VmStackType::Str => Opcode::StoreLocalStr,
VmStackType::Char => Opcode::StoreLocalChar,
VmStackType::Bool => Opcode::StoreLocalBool,
VmStackType::Object => Opcode::StoreLocalObj,
}
} else {
match self.convert_id_to_vm_ty(varty) {
VmStackType::Int => Opcode::StoreGlobalInt,
VmStackType::Float => Opcode::StoreGlobalFloat,
VmStackType::Str => Opcode::StoreGlobalStr,
VmStackType::Char => Opcode::StoreGlobalChar,
VmStackType::Bool => Opcode::StoreGlobalBool,
VmStackType::Object => Opcode::StoreGlobalObj,
}
},
var_addr,
);
let objsz = self.get_ty_sz(varty);
if !is_global {
self.add_double_bycode(Opcode::StoreLocal, var_addr, objsz);
} else {
self.add_double_bycode(Opcode::StoreGlobal, var_addr, objsz);
}
}

/// 生成新建变量的指令
Expand Down Expand Up @@ -1107,7 +1091,7 @@ impl<'a> AstBuilder<'a> {
// 本行是为了跳转到下一个分支
self.add_bycode(Opcode::JumpIfFalse, ARG_WRONG);
self.lex_until(RightBigBrace)?;
self.staticdata.inst[op_idx].operand = self.staticdata.get_next_opcode_id();
self.staticdata.inst[op_idx].operand.0 = self.staticdata.get_next_opcode_id();
self.add_bycode(Opcode::Jump, ARG_WRONG);
save_jump_opcode_idx.push(self.staticdata.get_last_opcode_id());
let t = self.token_lexer.next_token()?;
Expand All @@ -1129,7 +1113,7 @@ impl<'a> AstBuilder<'a> {
break;
}
for i in save_jump_opcode_idx {
self.staticdata.inst[i].operand = self.staticdata.get_next_opcode_id();
self.staticdata.inst[i].operand.0 = self.staticdata.get_next_opcode_id();
}
Ok(())
}
Expand Down
29 changes: 20 additions & 9 deletions src/compiler/ast/ast_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::compiler::token::TokenType;
use crate::compiler::{scope::SymScope, token::ConstPoolIndexTy};
use libcore::*;
use rust_i18n::t;
use std::{cell::RefCell, mem::size_of, rc::Rc};
use std::{cell::RefCell, rc::Rc};

impl<'a> AstBuilder<'a> {
pub fn clear_inst(&mut self) {
Expand All @@ -26,12 +26,12 @@ impl<'a> AstBuilder<'a> {
/// 获取对应类型的真实大小(内存对齐后)
pub fn get_ty_sz(&self, id: TyIdxTy) -> usize {
match self.convert_id_to_vm_ty(id) {
VmStackType::Int => size_of::<i64>(),
VmStackType::Float => size_of::<f64>(),
VmStackType::Str => size_of::<*mut String>(),
VmStackType::Char => size_of::<char>(),
VmStackType::Bool => size_of::<bool>(),
VmStackType::Object => get_trcobj_sz(),
VmStackType::Int => intsz!(),
VmStackType::Float => floatsz!(),
VmStackType::Str => strsz!(),
VmStackType::Char => charsz!(),
VmStackType::Bool => boolsz!(),
VmStackType::Object => objsz!(),
}
}

Expand Down Expand Up @@ -121,8 +121,7 @@ impl<'a> AstBuilder<'a> {
}
}

pub fn add_bycode(&mut self, opty: Opcode, opnum: usize) {
self.staticdata.inst.push(Inst::new(opty, opnum));
fn gen_line_table(&mut self) {
if !self.token_lexer.compiler_data.option.optimize {
// 不生成行号表了
self.staticdata
Expand All @@ -131,6 +130,18 @@ impl<'a> AstBuilder<'a> {
}
}

pub fn add_bycode(&mut self, opty: Opcode, opnum: usize) {
self.staticdata.inst.push(Inst::new_single(opty, opnum));
self.gen_line_table();
}

pub fn add_double_bycode(&mut self, opty: Opcode, opnum1: usize, opnum2: usize) {
self.staticdata
.inst
.push(Inst::new_double(opty, opnum1, opnum2));
self.gen_line_table();
}

pub fn gen_args_error(&mut self, info: ArguError) -> ErrorInfo {
match info {
ArguError::TypeNotMatch(ArgumentError { expected, actual }) => ErrorInfo::new(
Expand Down
Loading

0 comments on commit 122cedb

Please sign in to comment.