Methods and Initializers

1 Method Declarations

這回不從comipler開始,從runtime開始。

GC也需要follow

接下來難點在于如何填充這些表

2 Compiling method declarations

難點:

一個類可以聲明任意數量的方法。運行時需要查找并綁定所有這些方法。如果將這些方法都打包到一條 OP_CLASS 指令中,工作量會非常大。

解決方案

編譯器會發出一條 OP_CLASS 指令,創建一個新的空 ObjClass 對象。然后,編譯器會發出指令,將該類存儲到一個帶有其名稱的變量中。

這里有點像Closure。 emit OP_CLOSURE后,把upvalue 的內容放到這個指令之后。

Method也是。和OP_METHOD是分開的指令。

3 定義Method

現在,對于每個方法聲明,我們都會發出一條新的 OP_METHOD 指令,為該類添加一個方法。當所有 OP_METHOD 指令都執行完畢后,我們就得到了一個完整的類。在用戶看來,類的聲明是一個單一的atomic操作,而虛擬機則將其作為一系列mutation來實現。

3.1 具體實現

identifier 放到 constant里。把constant的index當做OP_METHOD的operand

function函數會 compile 函數parameters 還有body

然后emit ObjClosure

3.2 去哪找class?然后bind method?

Class的定義可能在stack上,可能在global。

因此

編譯時記錄下class的名字

當編譯method以前,先將這個class 調出來放到棧上,namedVariable可以來做這件事情

----

defineVariable也會做這件事(global),但是下一章這兩個call之間有東西,所以不這么干

----

所以編譯完method后要pop出來那個class

3.3 給一個例子

回頭看下為什么OP_CLOSURE之后會pop出來

-----

這OP_CLOSURE 會把function 放到stack。

OP_METHOD會把Closure pop出來?

右側是執行完左側后 stack的樣子。

-----

3.4 運行時,OP_METHOD

之后會把closure pop出來。

4 Method References

兩種情況都要支持

4.1 第一步

需要用“.”來得到method

但要記住,這里需要bind instance的state

舉例,這里應該打出來 jane

jlox中,用的是heap allcoated Environment class。

但是clox,有臨時變量在stack,還有在global的table中的,還有在closure的upvalue。

所以需要一個新的class

5 Bound Method(來自 CPython)

receiver 其實只能是ObjInstance。但是這里為了兼容更多函數,所以用了這個

配套代碼

這樣可以確保method句柄在內存中保留receiver,以便以后調用句柄時仍能找到對象。我們還會跟蹤method closure。

隱藏實現,所以類似打印function

這是最后一個runtime Obj tyep 牛逼

6 Accessing Methods

改下OP_GET_PROPERTY?

---

原來的

----

具體,先找method,如果不在就報錯。

如果有,就bind method

然后把instance pop 出去,把method放到棧上。

7 bind 的例子

把instance 和 ObjClosure 結合

8 Calling Method?

---

---

目前可以run這樣的函數了

但是目前沒有用instance 的狀態

8 使用This

把這個this 當作局部變量,這樣可以復用很多處理。closure也可以用

false的意思是 是不是canAssign 。這里永遠是false。

variable函數不在乎this 有自己的token 或者不是identifier

要考慮instance 什么時候要進入到memory

至少要在capture closure 以前,clox把所有local variable 在stack上。

每個參數會給自己在stack上有個占位。empty string

那個位置是為method留著的。那里會存this ,也就是instance

這個例子

應該打印 Nested instance

8.1 為此添加

runtime的時候, receiver不在slot zero。要這樣修一下,那里原來是什么?

如果是call 的話, 那里原來是 fn function。現在換成了instance

8.2 this 的錯誤使用

全局放個currentClass

這個類用于 放完nearest enclosing function 又來看繼承

我們創建一個鏈表,用來串起來所有nest class

編譯class時,會隱式的把當前的放到linked stack上

這個classCompiler或者C的stack上。

結束時,pop他,c 會自動回收他

這里就可以檢查是否在class 里面了。

9 Instance Initializers

對initializer的要求

大概這個邏輯

9.1 invoke initializer

例子

init() 方法的新 CallFrame 共享該堆棧窗口,因此這些參數會隱式地轉發給初始化器。

init()后面時"egg" 還有“coffee”

如果沒有定義init函數,但是傳進了參數,就報錯

因為每次創建instance 都要找init ,所有就提前創建這個string,就可以用intern string了

這里有個潛在的bug就是copyString 可能調用GC,這時訪問他就掛了。

所以要給個初值。

9.2 initializer return values

確保initializer 會返回新的instance,而不是nil或者其他東西。

只要初始化方法返回,用戶調用類創建實例的過程就會結束,并在堆棧中留下初始化方法的任何值。這意味著,除非用戶在初始化方法的末尾加上 return this;,否則不會有實例產生。這并不是很有用。

為了解決這個,單獨為initializer設置一個類型。單獨處理。

9.3 Incorrect returns ini initializers

防止他提前返回

10?Optimized Invocations

method invocation= accessing the method + calling the result

現狀支持

?但是效果不好

但是,總是將這些操作作為單獨的操作執行會帶來很大的代價。每次 Lox 程序訪問和調用一個方法時,運行時堆都會分配一個新的 ObjBoundMethod,初始化其字段,然后再將其拉出。之后,GC 必須花費時間釋放所有這些短暫的綁定方法。ObjBoundMethod 不用每次都new 吧

實際上,Compiler可以看到訪問method 然后立即call it

所以可以有個單獨的指令 來完成這兩個操作

---

如果看下bytecode的運行情況,發現有很多OP_XXX都是成組重復出現。

可以把這些instruction組合起來,叫superinstruction?

影響表現表現最大的overhead之一,就是decoding and dispatching each instruction

還不能加太多instruction,否則可能decoding變慢。

----

10.1 代碼這樣改

OP_INVOKE? 有兩個operand

  1. The index of the property name in the constant table.

  2. The number of arguments passed to the method.

假設invoke成功,最后更新frame

invoke()函數,先得到instance。要檢查下。

但是好像并沒有bind?

這里都不用bind。因為receiver and method都在正確的位置,之后舉個例子

快了好多,10s能夠call的次數

10.2 如果是field 有點問題

這里和invoke處理的稍微不同。這里的. 是access field。這個filed 被賦值為一個函數。這個field本身不是method。

---

有時有些錯誤,但是算的很快也可以接受。這是Monte Carlo algorithms.

---

這樣修改

在找method之前,先找field。

如果找到了,就把他放到receiver的位置。因為他不是medthod,所以不要instance。

invoke的總結

11 language design

?I believe this is one of the fundamental balancing acts of language design: similarity to other languages lowers learning cost, while divergence raises the compelling advantages.

novelty budget,?idiosyncrasy credit,

作者牛逼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62332.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62332.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62332.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

飛飛5.4游戲源碼(客戶端+服務端+工具完整源代碼+5.3fix+5.4patch+數據庫可編譯進游戲)

飛飛5.4游戲源碼(客戶端服務端工具完整源代碼5.3fix5.4patch數據庫可編譯進游戲) 下載地址: 通過網盤分享的文件:【源碼】飛飛5.4游戲源碼(客戶端服務端工具完整源代碼5.3fix5.4patch數據庫可編譯進游戲) 鏈…

開源C代碼之路:一、Gitee

開源c代碼之路:一,Gitee 前言1、開源項目2、從哪里找?3、舉個例子4、總結: 本系列回顧清單開源代碼示例 前言 從開源開發的角度,由淺入深,一步步初探C語言編程的入門之路。 本篇講解:Gitee 1…

基于協同過濾算法的寵物用品商城的設計與實現(計算機畢業設計)Java Spring 衍生為任何商城系統 畢業論文

系統合集跳轉 源碼獲取鏈接 一、系統環境 運行環境: 最好是java jdk 1.8,我們在這個平臺上運行的。其他版本理論上也可以。 IDE環境: Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat環境: Tomcat 7.x,8.x,9.x版本均可 操作系統…

算法-字符串-165.比較版本號

一、題目 二、思路解析 1.思路: 比較的是兩個版本號它們以“.”作為分割的部分的有效值(即數值)是否一致 2.常用方法: 1.s.split("\\規則"),將字符串按參數規則進行分割并存儲在字符串數組中 String[] str …

MySQL(四)--索引

MySQL的服務器,本質是在內存中的,那么所有對數據的CURD操作,全都是在對內存進行操作。 而,提高數據的CURD操作的效率,有兩種方式:1、組織數據的格式(數據結構);2、算法。 而,數據結構,就是索引,即組織數據的格式。 1、沒有索引的問題 索引:提高數據庫的性能,索…

C# (WinForms) 使用 iTextSharp 庫將圖片轉換為 PDF

iTextSharp簡介 iTextSharp 是一個開源的 .NET 庫,主要用于創建和操作 PDF 文檔。它是 iText 的 .NET 版本,iText 是一個廣泛使用的 Java 庫。iTextSharp 繼承了 iText 的核心功能并進行了適應 .NET 平臺的調整。 iTextSharp 的主要功能包括&#xff1a…

ubuntu防火墻設置(四)——iptables語法與防火墻基礎配置

前面介紹的ufw和firewall-config均為iptables的前端, 分別適合個人用戶和服務器網絡管理 下面介紹底層——ipables iptables是一個強大的工具,用于配置Linux系統的防火墻。以下是一些基本的使用方法和示例,幫助您入門: 基本語法 …

【中間件開發】Redis基礎命令詳解及概念介紹

文章目錄 前言一、Redis相關命令詳解及原理1.1 string、set、zset、list、hash1.1.1 string1.1.2 list1.1.3 hash1.1.4 set1.1.5 zset 1.2 分布式鎖的實現1.3 lua腳本解決ACID原子性1.4 Redis事務的ACID性質分析 二、Redis協議與異步方式2.1 Redis協議解析2.1.1 redis pipeline…

力扣每日一題 - 999. 可以被一步捕獲的棋子數

題目 還需要你前往力扣官網查看詳細的題目要求 地址 1.給定一個 8 x 8 的棋盤,只有一個 白色的車,用字符 R 表示。棋盤上還可能存在白色的象 B 以及黑色的卒 p。空方塊用字符 . 表示。2.車可以按水平或豎直方向(上,下,…

[UVM]在UVM環境中加入C++內存模塊

摘要:要在UVM環境中實現一個內存模塊并存入數據,您可以遵循以下步驟。這里會涉及C的內存建模和UVM的SystemVerilog部分的接口。在高層次上,我們將描述如何在C中實現內存模型并通過UVM的DPI接口訪問它。 一、C內存模型 首先,在C中…

學習記錄,正則表達式, 隱式轉換

正則表達式 \\:表示正則表達式 W: 表示一個非字(不是一個字,例如:空格,逗號,句號) W: 多個非字 基本組成部分 1.字符字面量: 普通字符:在正則表達式中,大…

Selenium是廣泛使用的模擬瀏覽器運行的庫

簡介 Selenium是廣泛使用的模擬瀏覽器運行的庫,它是一個用于Web應用程序測試的工具。 Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣,并且支持大多數現代 Web 瀏覽器。 環境 安裝 pip install selenium下載Chrome驅動 系統環境…

網絡練級寶典-> UDP傳輸層協議

目錄 傳輸層 端口號 端口號和進程的關系 UDP協議 UDP協議格式 UDP數據封裝: UDP數據分用: 面向數據報 UDP的緩沖區 UDP的缺點 基于UDP的應用層協議 傳輸層 端口號 我們知道端口號對應的其實就是一個進程的pid,在操作系統中二者的…

Redis原理—1.Redis數據結構

大綱 1.Redis的數據結構 2.Redis的SDS 3.Redis的鏈表 4.Redis的字典 5.Redis的跳躍表 6.Redis的整數集合 7.Redis的壓縮列表 8.Redis的對象 9.Redis對象的幾個關鍵屬性 10.Redis的單線程為什么這么快 11.Redis的典型應用場景和說明 12.Redis的相關命令說明 1.Redis…

【Vue3中Router使用】

Vue3中Router使用 1. 安裝vue-router組件2. 建兩個測試頁面2.1 測試頁面Home.vue2.2 測試頁面Category.vue 3. 創建路由對象4. 在入口main.js中引入router把App.vue改成路由頁面5. 測試5.1 關閉檢查解決ESlint報錯5.2 改文件名解決ESlint檢查報錯測試WebHashHistory 和WebHisto…

python拆分Excel文件

按Sheet拆分Excel 或 按照某一列的不同值拆分Excel。文檔樣式如下: 結果:紅色是按照Sheet名拆出的,藍色和橙色是某個Sheet按照某列的不同值拆分的。 代碼: # -*- coding: utf-8 -*- """ 拆分excel文件——按照…

交易所 Level-2 歷史行情數據自動化導入攻略

用戶部署完 DolphinDB 后,需要將歷史股票數據批量導入數據庫,再進行數據查詢、計算和分析等操作。DolphinDB 開發了 ExchData 模塊,主要用于滬深交易所 Level-2 行情原始數據的自動化導入,目前已支持的數據源包括: 滬…

開源ISP介紹(2)————嵌入式Vitis搭建

Vivado搭建參考前一節Vivado基于IP核的視頻處理框架搭建: 開源ISP介紹(1)——開源ISP的Vivado框架搭建-CSDN博客 導出Hardware 在vivado中導出Hardware文件,成功綜合—實現—生成比特流后導出硬件.xsa文件。(注意導…

Node.js JWT認證教程

Node.js JWT認證教程 1. 項目介紹 JSON Web Token (JWT) 是一種安全的跨域身份驗證解決方案,在現代Web應用中廣泛使用。本教程將詳細講解如何在Node.js中實現JWT認證。 2. 項目準備 2.1 初始化項目 # 創建項目目錄 mkdir nodejs-jwt-auth cd nodejs-jwt-auth# …

109.【C語言】數據結構之二叉樹層序遍歷

目錄 1.知識回顧 2.代碼實現 準備工作 LevelOrder函數 代碼框架 關鍵代碼 3.執行結果 1.知識回顧 層序遍歷參見106.【C語言】數據結構之二叉樹的三種遞歸遍歷方式文章 截取的部分內容 定義:按層的方式遍歷(,設n為樹的深度,h1-->h2-->h3-->...-->hn) 以下面…