欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

嘗試寫一個(gè)jvm吧(二)

今天清明節(jié),剛好放假更新第二章,就是讀取字節(jié)碼文件。 一個(gè)更舒適的UI:https://www.mdnice.com/writing/d1c0dc8c7bbc4ef3bf5f5a2ae3e10f97 前面兩節(jié)都比較簡(jiǎn)單,分別是命令行操作和讀取class文件,從第三節(jié)開始估計(jì)進(jìn)度會(huì)慢一些和復(fù)雜一點(diǎn)點(diǎn),要開始寫運(yùn)行時(shí)和解析class文件了~

首先,我們還是通過命令行來進(jìn)行操作,所以首先在command.rs文件中加入以下指令

command結(jié)構(gòu)體

#[derive(Debug)]
pub struct Command {
    pub help_flag: bool,
    pub version_flag: bool,
    pub info_flag: bool,
    pub cp_option: String,
    pub x_jre_option: String,
    pub class: String,
    pub args: Vec<String>,
}

命令行操作命令

opts.optopt("", "classpath", "Specify the classpath", "classpath");
opts.optopt("", "cp", "Specify the classpath", "classpath");
opts.optopt("", "Xjre", "Path to jre", "jre");

對(duì)命令進(jìn)行解析

match matches.opt_str("classpath") {
    Some(classpath) => {
        command.cp_option = classpath;
    },
    None => {
        match matches.opt_str("cp") {
            Some(cp) => {
                command.cp_option = cp;
            },
            None => {}
        }
    }
}

match matches.opt_str("Xjre") {
    Some(x_jre_option) => {
        command.x_jre_option = x_jre_option;
    },
    None => {}
}

// 未定義的參數(shù)放在 free Vec 中
if !matches.free.is_empty() {
    command.class = matches.free[0].clone();
    command.args = matches.free[1..].to_vec();
}

上面就是命令行解析的內(nèi)容了,命令行解析完后,我們要通過讀取的命令解析執(zhí)行對(duì)應(yīng)的步驟,比如我輸入下面的命令

  • java -classpath xxx/xx/xxx/xx java.lang.Object

就應(yīng)該可以讀取Objecgt的文件數(shù)據(jù),不過肯定是二進(jìn)制格式的,所以需要定義一個(gè)讀取classpath的包。當(dāng)前就暫且叫做classpath

這兒我們還是先引入一些必要依賴

Cargo.toml文件

mockall = "0.11.3"
zip = {version = "0.6.4", default-features = false, features = ["deflate"]}
tokio = {version = "1.26.0",  features = ["full"]}
  • mockall 是用來寫單測(cè)的,好的開發(fā)者應(yīng)該對(duì)于每一個(gè)module的開發(fā)都有完善的單測(cè)驗(yàn)證自己的邏輯
  • zip是壓縮包,用于讀取類似.jar 或者 .zip 或者 .war 或者 .rar 等文件,可能更多的是jar包,不過我們把其他壓縮包也考慮進(jìn)去
  • tokio 是用來實(shí)現(xiàn)一個(gè)自定義線程池,可以實(shí)現(xiàn)IPC高性能通信那種,當(dāng)然這個(gè)是一個(gè)優(yōu)化點(diǎn),后續(xù)會(huì)考慮慢慢實(shí)現(xiàn),不做也不影響整個(gè)項(xiàng)目的開發(fā)

首先是項(xiàng)目結(jié)構(gòu),目前我們考慮有通過 絕對(duì)路徑去獲取class文件的,也有通過xx/*等方式獲取的,也有.jar的壓縮文件,也有讀取多個(gè)文件的,所以我們定義四個(gè)rs文件來區(qū)分它們

alt

classpath 中需要定義兩個(gè)重要的方法 分別是 parse() 和 read_class(), 但是考慮到讀取class是一個(gè)通用的方法,需要讀取不同種類的文件,所以就準(zhǔn)備定義成一個(gè)trait來使用

::: block-1

這兒說的trait,用java和go的看法來說,就是接口,不過在rust中叫特征。 :::

所以我們定義一個(gè)公共的Entry,作為trait的入口

entry.rs

/// 目前有這么幾種文件對(duì)象
/// -classpath file => 目錄形式的類路徑 entry_dir.rs
/// -classpath file1.jar:file2.jar:file3.jar  => 多個(gè)文件對(duì)象組成的類路徑 entry_multiple.rs
/// -classpath file/*  => 以*結(jié)尾的路徑 entry_wildcard.rs
/// -classpath file.jar => 壓縮文件路徑 entry_compression.rs
pub trait Entry: fmt::Display {
    fn read_class(&mut self, class_name: &str) -> Result<Vec<u8>, String>;
}

同時(shí)在classpath中定義我們之前說好的兩個(gè)方法,分別作解析和讀取文件數(shù)據(jù)。

classpath.rs

impl Classpath {
    pub fn parse(jre_option: &str, cp_option: &str) -> Self {
    // 加載 boot_classpath
    // 加載 ext_classpath
    // 加載 user_classpath   
    todo!()
    }
}

impl Entry for Classpath {
    /// 讀取class數(shù)據(jù),從boot_classpath 
    /// 到 ext_classpath 到 user_classpath
    fn read_class(&mut self, class_name: &str) -> Result<Vec<u8>, String> {
   
        todo!()
    }
}
  • boot_classpath: jvm自帶類庫(kù),包含JavaSE核心類庫(kù),jvm啟動(dòng)時(shí)必用路徑,包含jre/lib/lib/rt.jar 和 jre/lib/ext 中的jar包
  • ext_classpath: jvm擴(kuò)展路徑,用于加載開發(fā)者自己編寫的擴(kuò)展類庫(kù)
  • user_classpath: 用戶自定義路徑,用于加載用戶自己編寫的java類

最后就是main方法的啟動(dòng),在一開始我們最后是start_jvm()方法來進(jìn)行啟動(dòng)的,所以我們也把解析class和讀取class的操作放在這個(gè)方法中

main.rs

fn start_jvm(cmd: Command) {
    info!("[WELCOME USE THIS JVM, It's named azh after my girlfriend, thanks]");
    let mut classpath = Classpath::parse(&cmd.x_jre_option, &cmd.cp_option);

    info!("classpath: {} class: {} args: {:?}", classpath, cmd.class, cmd.args);

    let class_name = cmd.class.replace(".", "/");
    let class_data = match classpath.read_class(&class_name) {
        Ok(class_data) => class_data,
        Err(err) => { panic!("Could not find or load main class {}: {}", cmd.class, err); },
    };
    info!("class data: {:?}", class_data)
}

上面就是整個(gè)大體步驟,整體脈絡(luò)就是兩步驟,解析classpath,讀取class文件,下一章會(huì)具體介紹jar、j*、(jar1,jar2)等文件的具體的parse方法和三種類路徑的parse方法。

可以自己先寫一下試試,對(duì)于單個(gè)class文件應(yīng)該不難,就是從中讀取二進(jìn)制數(shù)據(jù)而已。

::: block-2

之前說的線程池,主要是想實(shí)現(xiàn)一個(gè)IPC高性能的緩存buffer,其中盡量通過Arc等指令和避免Box來做到無鎖和不操作堆內(nèi)存來達(dá)到高性能,不過目前還在構(gòu)思當(dāng)中,當(dāng)前緩存的方案是想實(shí)現(xiàn)HotRing論文,可惜這個(gè)數(shù)據(jù)結(jié)構(gòu)并不是那么容易實(shí)現(xiàn),而且對(duì)于Rust寫鏈表,相信學(xué)過的人都知道,這算是一個(gè)勸退題了~ :::

#大廠##23屆找工作求助陣地##我的實(shí)習(xí)求職記錄##Java##實(shí)習(xí)#
全部評(píng)論
可以,很硬
1 回復(fù) 分享
發(fā)布于 2023-04-05 21:39 浙江
???
1 回復(fù) 分享
發(fā)布于 2023-04-05 17:57 湖北
NB
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2023-06-01 02:27 廣東
哥們你來真的?
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2023-05-07 11:09 四川

相關(guān)推薦

程序員小假:人才
點(diǎn)贊 評(píng)論 收藏
分享
04-30 21:35
已編輯
長(zhǎng)安大學(xué) C++
曉沐咕咕咕:評(píng)論區(qū)沒被女朋友好好對(duì)待過的計(jì)小將可真多。覺得可惜可以理解,畢竟一線大廠sp。但是罵樓主糊涂的大可不必,說什么會(huì)被社會(huì)毒打更是丟人。女朋友體制內(nèi)生活有保障,讀研女朋友還供著,都準(zhǔn)備訂婚了人家兩情相悅,二線本地以后兩口子日子美滋滋,哪輪到你一個(gè)一線城市房子都買不起的996清高計(jì)小將在這說人家傻??
點(diǎn)贊 評(píng)論 收藏
分享
評(píng)論
6
8
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
牛客企業(yè)服務(wù)