ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【深入理解 quickjs 系列】01. 前置概念整理

2022-05-12 23:31:22  阅读:173  来源: 互联网

标签:01 currentNode 虚拟机 前置 char quickjs 寄存器 newNode operation



    

虚拟机类型

栈式虚拟机

虚拟机会在其内部维护一个全局指令指针来指向下一条将要执行的指令所在位置。

堆栈机使用栈结构来作为暂存数据的容器,这使得我们无法对栈容器中的数据进行任意读取,我们需要遵循LIFO的数据操作原则来对数据进行处理。这导致无法从源代码直接生成最高效的虚拟机代码,因为对于某些较为复杂的语句来说,可能会涉及栈数据频繁交换的过程。但另一方面,基于栈结构实现的虚拟机模型最简单,所生成的虚拟机代码密度适中。

寄存式虚拟机

在寄存器型虚拟机中,需要为每一条指令都指定其操作数所在的寄存器地址,因此与堆栈机和累加器型虚拟机相比,寄存器型虚拟机的平均指令更长。

寄存器型虚拟机将操作数存储在多个不同的寄存器单元上,这使得每条指令在执行时都需要指定操作数所在的寄存器地址,而这无疑增加了指令的长度,同时也使虚拟机的实现变得复杂。但是存在多个寄存器单元为寄存器型虚拟机提供了更大的优化空间,因此可以生成执行效率更高的虚拟机代码。

如何将一个计算表达式变为中序表达式

栈式计算机在处理运算的时候用的逆波兰表达式,如何将一个计算表达变为一个树,然后用后序遍历生成逆波兰表达式,如下所示代码

function buildTree(s) {
  let root = {};
  let currentNode = root;
  
  for (let i = 0, length = s.length; i < length; i++) {
    let char = s.charAt(i);
    if (/[0-9]/.test(char)) {
      let number = char;
      while (/[0-9]/.test(s[i + 1])) {
        char = s[i + 1];
        number += char;
        i = i + 1;
      }
      if (currentNode.left == null) {
        currentNode.left = { value: parseInt(number, 10) };
      } else if (currentNode.right == null) {
        currentNode.right = { value: parseInt(number, 10) };
      }
    }
    
    if (["+", "-", "*", "/"].includes(char)) {
      if (currentNode.operation == null) {
        currentNode.operation = char;
      } else {
        const newNode = { operation: char };
        if (
          ["+", "-"].includes(currentNode.operation) &&
          ["*", "/"].includes(newNode.operation)
        ) {
          newNode.left = { ...currentNode.right };
          currentNode.right = newNode;
          newNode.parent = currentNode;
        } else if (
          ["*", "/"].includes(currentNode.operation) &&
          ["*", "/"].includes(newNode.operation)
        ) {
          if (!currentNode.parent) {
            newNode.left = currentNode;
            currentNode.parent = newNode;
            root = newNode;
          } else {
            currentNode.parent.right = newNode;
            newNode.parent = currentNode.parent;
            newNode.left = currentNode;
          }
        } else {
          newNode.left = root;
          root.parent = newNode;
          root = newNode;
        }
        currentNode = newNode;
      }
    }
  }
  
  return root;
}

类似的代码可以在Github上搜索到 “如何编写一个计算器”

opcode vs bytecode

quickjs 里通过将脚本变为 opcode,来执行代码

他们本质都是类似的,都是指令,告诉执行容器执行逻辑是什么。唯一的区别就是 Opcode 是面向硬件的,bytebode 是面向虚拟机的。但是目前来看 quickjs 的 opcode 也是面向虚拟机的。

标签:01,currentNode,虚拟机,前置,char,quickjs,寄存器,newNode,operation
来源: https://www.cnblogs.com/xiaoniuzai/p/16264953.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有