CSE 390 B Spring 2020 Project 7 Tips & Virtual Machine
Transcript of CSE 390 B Spring 2020 Project 7 Tips & Virtual Machine
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
CSE 390 B Spring 2020
Project 7 Tips & Virtual Machine
Compiler Recap, Project 7 Tips, Two-Tier Compilation, Implementing a Stack Machine
Significant material adapted from www.nand2tetris.org. © Noam Nisan and Shimon Schocken.
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Agenda
❖ Morning Warm-up Question
❖ Project 7: The Compiler▪ Recap: Code Generation
▪ Project 7 Specific Tips
❖ Virtual Machine▪ Two-Tier Compilation
▪ Implementing a Stack Machine
2
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
If you could have a 30 minute zoom meeting with any person in the world, who would it be and
why?
3
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Agenda
❖ Morning Warm-up Question
❖ Project 7: The Compiler▪ Recap: Code Generation
▪ Project 7 Specific Tips
❖ Virtual Machine▪ Two-Tier Compilation
▪ Implementing a Stack Machine
4
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
pollev.com/cse390b
5
Pulse Check: How far are you on Project 7?
A I haven’t looked at it yet
BI’ve looked at the spec and/or starter code but haven’t started the implementation
C I’ve started working on NumberLiteral.java (Step 1)
D I’ve started working on Plus.java (Step 2)
E I’ve started working on Minus.java or beyond (Step 3+)
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Project 7
● Part I: Buggy Compiler!
6
● Part II: Meeting 1:1 with a TA○ Check email: Doodle
link to sign up for your meeting
● Part III: Project 7 Reflection
Project 7 is due Thursday (5/28)
0 Read starter code
1Implement NumberLiteral.java
~4 Lines
2DebugPlus.java
2 Bugs
3ImplementMinus.java
~13 Lines(similar to Plus)
4Implement NotEquals.java
~21 Lines(similar to Equals)
5Implement ArrayVarAccess.java
~3 Lines
6DebugIf.java
2 Bugs
7ImplementWhile.java
~14 Lines
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Recap: Code Generation -- The Task
7
Abstract Syntax Tree
PLUS
NUM(2) NUM(3)
left right
@2 D=A @3 D=D+A
Hack Assembly
● Convert the Abstract Syntax Tree into target language code (For us, Hack ASM) that produces the specified behavior
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Recap: Code Generation -- Our Approach
● Human intuition can produce “beautiful” (read: short and efficient) programs
● Computers need automatic rules that cover all cases○ Goal in Project 7: reliability, not efficiency!
8
Abstract Syntax Tree
PLUS
NUM(2) NUM(3)
left right
@2 D=A @3 D=D+A
Hack Assembly
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Abstract Syntax Tree
PLUS
NUM(2) NUM(3)
left right
Recap: Code Generation -- Our Approach
Our compiler guided by two fundamental principles:
9
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Recap: Code Generation -- Our Approach
Our compiler guided by two fundamental principles:
10
1. Each AST Node knows how to generate its own chunk of code
Abstract Syntax Tree
PLUS
NUM(2) NUM(3)
left right
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
read from R0
read from R0
Recap: Code Generation -- Our Approach
Our compiler guided by two fundamental principles:
11
1. Each AST Node knows how to generate its own chunk of code
Abstract Syntax Tree
PLUS
NUM(2) NUM(3)
left right
write to R0write to R0
write to R0
write to R0
2. AST Node generated code “communicates” through convention: put result in R0
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Recap: Using a Stack
12
NU
M(2
)
PLU
S
PLU
S
● Solves nested expression problem
● We’ll keep a stack starting at memory address 1024○ R1 is “stack pointer”: always
stores address of the last used stack position
○ push() and pop() do most of the work for you
1025 2 1
R1 1024 1025 1026 1027
Abstract Syntax Tree
PLUS
NUM(2) PLUS
left right
NUM(1) NUM(4)
left right
NU
M(1
)N
UM
(4)
2 --> R0
push R0
1 --> R0
push R0
4 --> R0
pop, add R0result --> R0
pop, add R0result --> R0
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Agenda
❖ Morning Warm-up Question
❖ Project 7: The Compiler▪ Recap: Code Generation
▪ Project 7 Specific Tips
❖ Virtual Machine▪ Two-Tier Compilation
▪ Implementing a Stack Machine
13
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Abstract Syntax Tree
Example: Number Literal (Step 1)
● Called a “literal” because it’s a literal value embedded in the MicroJack code○ Generated Hack ASM should simply put that value in R0
14
4MicroJack Code
NUM(4)
@4D=A@R0M=D
Hack ASM
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Example: Number Literal (Step 1)
15
public class NumberLiteral extends Expression { public int value;
public NumberLiteral(String value) { this.value = Integer.parseInt(value); }
@Override public void printASM() { comment("Start Number Literal"); instr( ); instr("D=A"); instr("@R0"); instr("M=D"); comment("End Number Literal"); }
@Override public String toString() { return Integer.toString(value); }}
// Start Number Literal @4 D=A @R0 M=D // End Number Literal
?
4
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Example: Number Literal (Step 1)
16
public class NumberLiteral extends Expression { public int value;
public NumberLiteral(String value) { this.value = Integer.parseInt(value); }
@Override public void printASM() { comment("Start Number Literal"); instr("@" + toString()); instr("D=A"); instr("@R0"); instr("M=D"); comment("End Number Literal"); }
@Override public String toString() { return Integer.toString(value); }}
// Start Number Literal @4 D=A @R0 M=D // End Number Literal
4
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Example: Number Literal (Step 1)
17
Compile Time
● Java (the compiler) is running
● 4 is stored as value field inside an NumberLiteral ASTNode
● When executed, prints code that stores it another way!
Run Time
● Hack ASM (the output) is running
● 4 is stored as constant inside an assembly instruction
● When executed, loads 4 from instruction into A register
public class NumberLiteral extends Expression { public int value;
public NumberLiteral(String value) { this.value = Integer.parseInt(value); }
@Override public void printASM() { comment("Start Number Literal"); instr("@" + toString()); instr("D=A"); instr("@R0"); instr("M=D"); comment("End Number Literal"); }
@Override public String toString() { return Integer.toString(value); }}
// Start Number Literal @4 D=A @R0 M=D // End Number Literal
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Example: Plus (Step 2)
18
public class Plus extends Expression { public Expression left; public Expression right;
@Override public void printASM() { comment("Start Plus");
left.printASM(); instr("@R0"); instr("D=M");
right.printASM();
push();
instr("@R1"); instr("A=M");
instr("D=D+A", "perform the addition");
...
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Example: Plus (Step 2)
19
public class Plus extends Expression { public Expression left; public Expression right;
@Override public void printASM() { comment("Start Plus");
left.printASM(); instr("@R0"); instr("D=M");
right.printASM();
push();
instr("@R1"); instr("A=M");
instr("D=D+A", "perform the addition");
...
NU
M(2
)N
UM
(3)
PLU
S
2 --> R0
push R0
3 --> R0
pop, add R0result --> R0
1 Structural Bug: Map to abstract diagram for Plus:
1 Detail Bug: Step through generated code, Check state at each step
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Project 7: MicroJack Language Gotchas
● Can’t write a negative integer literal○ Instead, use subtraction from zero: 0 - 1
● All variable declarations must come before all regular statements○ (Why? Simplifies concept of a “defined” variable)
● No defined operator precedence○ If order matters for an operation, use parentheses
● Arrays are very simple
○ arr[index] is really just calculating an address: take address of arr variable and add index to it as an offset
○ No array bounds checking -- just lets you run off the end
● “Booleans” are just 0 (false) and non-zero (true)20
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Project 7: Debugging Tips
● Try walking through the general printASM code to understand why each line is there○ Add comments to the assembly as you go! Much easier to
understand resulting file
● Find the smallest example you can○ Provided tests get progressively more complex, but you may
want to write your own tiny test case to isolate○ ASM gets long fast -- we’ve added comments so you can isolate
to the section you’re working on
● “Play Computer”: as you step through the code, write down the state you expect after each instruction, then advance and see if the CPUEmulator agrees
21
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Agenda
❖ Morning Warm-up Question
❖ Project 7: The Compiler▪ Recap: Code Generation
▪ Project 7 Specific Tips
❖ Virtual Machine▪ Two-Tier Compilation
▪ Implementing a Stack Machine
22
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Roadmap
23
High-Level Language
Intermediate Language(s)
Assembly Language
Machine Code
Operating System
Computer
CPUMemory
ALU
Basic Logic Gates
NAND
SOFTWARE
HARDWARE
PC
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
SoftwareOverview
x86, x86-64ARM
RISC-VHACK
Assembly Language
Machine Code
WindowsMac
Unix/LinuxAndroidHack OS
Operating System
SOFTWAREAssembler
Java Byte CodeJack VM Code
JavaPython
C/C++Jack
High-Level Language
Intermediate Language(s)
Compiler
Compiler
(VM Translator)
“Real-World” ExamplesOur Computer
KEY:
Compiler
(Your project 7)
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Compiling Code: Single Tier
25
High-Level Program
Device A Device B Device C Device D
Compiler for A Compiler
for B
Compiler for C
Compiler for D
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Compiling Code: Two Tier
26
High-Level Program
Device A Device B Device C Device D
VM Translatorfor A
Intermediate Program
VM Translatorfor B
VM Translatorfor C
VM Translatorfor D
Compiler for VM
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
The JVM
27
Java Code
Device A Device B Device C Device D
JVM Runtime for A
JVM
JVM Runtimefor B
JVM Runtimefor C
JVM Runtimefor D
Java Compiler
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
pollev.com/cse390b
28
Which of the following is NOT a benefit of the JVM two tier model?
AThe same compiled JVM bytecode can be re-used across devices
BThe same compiler (from Java to JVM bytecode) can be re-used across devices
CProgrammers don’t need to factor in differences between machine languages
DJava programs can run on a new device immediately after it is released
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Agenda
❖ Morning Warm-up Question
❖ Project 7: The Compiler▪ Recap: Code Generation
▪ Project 7 Specific Tips
❖ Virtual Machine▪ Two-Tier Compilation
▪ Implementing a Stack Machine
30
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
In Pursuit of Two-Tier Compiling
● To support two-tier compiling, we need an intermediate language○ Will run on a virtual machine (which we then implement on
each hardware)
31
High-Level Language
Assembly Language
Intermediate Language
We need:
Clear translation from high-level to intermediate
Clear translation from intermediate to assembly
Clear spec for intermediate language
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Hmm...
● Observation: our generated assembly pushes/pops things from a stack an awful lot
● If our assembly already inherently uses a stack, could we expand on that idea and use it as the entire basis for our intermediate language?○ Motivation: seems easy to translate from VM stack to the
assembly stack we have to implement anyway
32
Assembly Language
Intermediate Language
Clear translation from intermediate to assembly
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
A Stack Machine
33
memory stack
7
...
12
12
3
...
...
sp → x
y
● 3 Components:○ Program: a series of instructions (push, pop, or function)
○ Memory: a “giant array”
○ Stack: a stack data structure
● Remember: this is a virtual machine○ A theoretical architecture we can write programs for
○ Then, a virtual machine implementation can read that program and translate it to native assembly instructions
push 2push xsubpush y
VM Code
program
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Stack Machine Behavior
34
memory stack
7
...
12
12
3
...
...
sp → x
y
memory stack
7
...
12
12
3
7
...
...
sp →
x
y
memory stack
7
...
3
12
...
... sp →
x
y
push x
pop y
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Stack Machine Arithmetic
35
stack
12
3
sp →
● Invoking a function f on the stack means:○ Popping the needed number of arguments
○ Computing f on those arguments
○ Pushing the result
7
stack
12
10sp → add
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: High-Level to Stack Machine
● Is there a clear translation from a high-level language to our stack machine instructions?
● In this simple example, seems plausible!
36
push 2push xsubpop d
VM Code
d = (2 - x)
High-Level Language
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: Stack Machine to Assembly
● Is there a clear translation from stack machine instructions to assembly instructions?○ Keep track of stack using some @sp variable!
■ (Could very well be R1 from Project 7, but it doesn’t matter)
● We can implement push!
37
stack
...
...
sp → 2push 2
VM Code
@2D=A@spM=M+1A=MM=D
Hack ASM Code
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: Stack Machine to Assembly
● We can also implement pop!
● So far so good!
38
stack
...
...
sp → 2
pop x
VM Code
@spA=MD=M@{address of x}M=D@spM=M-1
VM Code
memory
7
...
3
...
...
x
y
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: What About Control Flow?
● To work with any reasonable high-level language, we need conditionals (If) and loops (While)
● Can we implement them with just push and pop?
39
push 2pop x
VM Code
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: What About Control Flow?
● To work with any reasonable high-level language, we need conditionals (If) and loops (While)
● Can we implement them with just push and pop?○ No -- we need a way to move around the program itself
● Can we add a new instruction?
40
push 2pop x
VM Code
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: What About Control Flow?
● To work with any reasonable high-level language, we need conditionals (If) and loops (While)
● Can we implement them with just push and pop?○ No -- we need a way to move around the program itself
● Can we add a new instruction?○ Absolutely -- the language can be whatever we want it to be! All
that matters is that we can translate to it from high-level, and translate from it to assembly language.
41
push 2pop xif-goto LOOP
VM Code
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: Control Flow
● Let’s add an if-goto VM command○ Syntax: if-goto LABEL
○ Behavior: will jump to LABEL in the program if a condition is met
○ How should we give it that condition?
42
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: Control Flow
● Let’s add an if-goto VM command○ Syntax: if-goto LABEL
○ Behavior: will jump to LABEL in the program if a condition is met
○ How should we give it that condition?■ Use the stack!■ Push false (0) or true (non-zero), then execute if-goto!■ Pops from the stack, then jumps if necessary
43
CSE 390B, Spring 2020L17: Project 7 Tips & Virtual Machine
Translating: Control Flow
● Let’s add an if-goto VM command○ Syntax: if-goto LABEL
○ Behavior: will jump to LABEL in the program if a condition is met
○ How should we give it that condition?■ Use the stack!■ Push false (0) or true (non-zero), then execute if-goto!■ Pops from the stack, then jumps if necessary
● Can we implement in Hack ASM?○ Yes, combine pop() implementation with a JNE C-instruction
○ We won’t reveal much more to avoid spoiling Project 7 :)
44