tutorial 3: code generation

54
Tutorial Code Generation Compiler Construction 1 S C I E N C E P A S S I O N T E C H N O L O G Y www.tugraz.at Tutorial 3: Code Generation Univ.-Prof. Dr. Franz Wotawa, DI Roxane Koitz, Stephan Frühwirt, Christopher Liebmann, Martin Zimmermann Institute for Software Technology

Upload: others

Post on 12-Dec-2021

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction1

S C I E N C E ■ P A S S I O N ■ T E C H N O L O G Y

u www.tugraz.at

Tutorial 3: Code Generation

Univ.-Prof. Dr. Franz Wotawa, DI Roxane Koitz,

Stephan Frühwirt, Christopher Liebmann, Martin

Zimmermann

Institute for Software Technology

Page 2: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction2

Jova Input Program

Java Byte Code

Compiler Phases

Page 3: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction3

Jova Input Program

Java Byte Code

Compiler Phases

Page 4: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction4

Source Code

(*.jova file)Syntax tree

Grammar

(Jova.g4)

ANTLR

Lexer and Parser

Lexical and

syntactical errors

Symbol

table

ANTLR

visitor / listener

Type checking

errors

Debugging

output

Debugging

output

Workflow (1/2)

Page 5: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction5

Syntax tree

Symbol

table

Workflow (2/2)

Jasmin code

(.j file)

Byte code

(.class file)

Jasmin

Page 6: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction6

What is Jasmin?

• Assembler for Java bytecode

• Input: <filename>.j file

• contains assembly of the original code

• written in Jasmin assembler language

• Output: executable Java .class file

Page 7: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction7

Pipeline

Create

Assembly

• Produce jasmin assembly

• Result: <filename>.j

Convert

• Invoke “java –jar jasmin.jar <filename>.j“

• Result: <filename>.class

Execute

• Invoke “java <filename>“

• Result: executes main method of class

Page 8: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction8

• One class per .j file

• One statement per line

• Assembly setup:

• Required options

• Methods

• Statements (JVM instructions)

Jasmin syntax

Page 9: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction9

File structure: Class options

▪ .source: Source of assembly▪ e.g.: .source MyClass.jova

▪ .class: Resulting java class description▪e.g.: .class public MyClass

▪ .super: Superclass of resulting java class▪always: .super java/lang/Object

▪ .field: Specify fields of class▪e.g.: .field public my_field I

Page 10: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction10

.method <method signature>

e.g. .method public myMethod(I)V

.limit stack n

n: choose realistic number

.limit locals n

n = #parameters + #local_vars + #temp_var

<instructions>

return

requires matching type on top-of-stack for non-void returns

(e.g. ireturn)

.end method

File structure: Methods

Page 11: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction11

Default Constructor

▪ needs to be defined for every class

▪ since Jova does not have Constructors you can

use the same definition for every class:

.method public <init>()V

.limit stack 1

.limit locals 1

aload_0

invokespecial java/lang/Object/<init>()V

return

.end method

Page 12: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction12

Example: DoNix

File: DoNix.j

.source noSource

.class public DoNix

.super java/lang/Object

.method public static main([Ljava/lang/String;)V

.limit stack 0

.limit locals 1

;nothing to do here

return

.end method

Page 13: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction13

• Two data structures per method (invocation/frame)

• Stack

• Local array

• Operations to manipulate both

• Build-in datatypes

• Primitive Types (int, float, byte, char,…)

• Reference Types (class types, array types,

interface types)

• Very limited support for boolean

Data Management

Page 14: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction14

• Each method has its own operand stack

• Size is definable per method

(just assume a realistic number)

• LIFO

• Stack operations

• Push values onto stack

• Pop/Fetch values from stack

• Instructions which require one or multiple values

on stack (order does matter!)

Data Management: Stack

Page 15: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction15

• Each method has its own local variable array

• Definable size for each method (0-based indices)

• Typing

• Can store arbitrary types

• Items need to be initialized before read access

• Contains

• Method parameters (stored in lowest indices)

• At index 0 the ‘this’ reference

Data Management: Local Variable Array

Page 16: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction16

Data Managment: Types

▪ … a few primitives▪Integer indicated by letter I▪Void indicated by letter V▪Boolean indicated by letter Z

▪ Objects following the format “Lpackage/Classname;“▪e.g. Ljava/lang/String; String object

▪ Array indicated by a leading [▪e.g. [Ljava/lang/String; array of Strings

Page 17: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction17

Instructions

▪ Can involve stack and local array

▪ Most instructions operate on expected types

▪ Instruction template: <T><instr>

where <T> = type letter

<instr> = operation▪ E.g.: iadd, fadd

▪ Instructions which do not operate on specific type▪ E.g.: swap, dup

Page 18: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction18

Instructions: Stack - Locals interaction

▪ iload n pushes integer, stored in index n of

local array, onto stack▪ istore n pops integer from stack and stores it

into index n of local array▪ aload n pushes object, stored in index n of

local array, onto stack▪ astore n pops object from stack and stores it

into index n of local array

Page 19: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction19

Instructions: Constants

▪ sipush n / bipush n

▪Pushes integer constant onto stack▪E.g. sipush 10

▪For m1 - 5 you can also use iconst_<n>

▪ ldc “<string>”

▪Pushes string constant <string> onto stack▪E.g. ldc “Hello World”

▪Note: Strings are Objects (variable access with

astore/aload)

Page 20: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction20

Instructions: Arithmetic Operators

▪ iadd add two integers

▪ isub subtract two integers

▪ imul multiply two integers

▪ idiv divide two integers

▪ irem modulo division of two integers

▪ ineg toggles sign of int on top of stack

Page 21: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction21

Example: BasicInstructions

File: BasicInstructions.j.source noSource

.class public BasicInstructions

.super java/lang/Object

.method public static main([Ljava/lang/String;)V

.limit stack 3

.limit locals 2

sipush 5 ;push integer 5 onto stack

istore 0 ;pop integer 5 and store in index 0

ldc "Hello i11" ;push string i11 onto stack

astore 1 ;store string in index 1

iload 0 ;load 5

dup ;duplicate stack entry 5

sipush 2 ;push integer 2 onto stack

isub ;pop 5 and 2 and store result 3 onto stack

iadd ;pop 5 and 3 and store result 8 onto stack

istore 0 ;store result 8 in index 0

return

.end method

Page 22: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction22

Example: BasicInstructions

File: BasicInstructions.j

sipush 5 local array

args

stack

Page 23: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction23

Example: BasicInstructions

File: BasicInstructions.j

istore 0

local array

args

stack

5

Page 24: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction24

Example: BasicInstructions

File: BasicInstructions.j

ldc "Hello i11"

local array

5

stack

Page 25: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction25

Example: BasicInstructions

File: BasicInstructions.j

astore 1

local array

5

stack

Hello i11

Page 26: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction26

Example: BasicInstructions

File: BasicInstructions.j

iload 0

local array

5 Hello i11

stack

Page 27: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction27

Example: BasicInstructions

File: BasicInstructions.j

dup

local array

5 Hello i11

stack

5

Page 28: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction28

Example: BasicInstructions

File: BasicInstructions.j

sipush 2

local array

5 Hello i11

stack

5

5

Page 29: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction29

Example: BasicInstructions

File: BasicInstructions.j

isub

local array

5 Hello i11

stack

5

5

2

Page 30: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction30

Example: BasicInstructions

File: BasicInstructions.j

iadd

local array

5 Hello i11

stack

5

3

Page 31: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction31

Example: BasicInstructions

File: BasicInstructions.j

istore 0

local array

5 Hello i11

stack

8

Page 32: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction32

Example: BasicInstructions

File: BasicInstructions.j

return

local array

8 Hello i11

stack

Page 33: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction33

Instructions: Logical Operators

▪ iand bitwise and of two integers

▪ ior bitwise or of two integers

▪ inot does not exist!

▪Note: Needs to be assembled using custom labels and

conditional jump operations

Page 34: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction34

Instructions: Relational Operators

▪ Do not exist!

▪ Need to be assembled using custom labels and

conditional jump operations

Page 35: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction35

Instructions: Labels and Jumps

▪ <labelname>:

▪sets a label in the assembly

▪ goto <labelname>

▪continues execution of current method at position of the

label <labelname>

▪ if_icmpXX <labelname>

▪pops two elements of the stack, relates them and jumps

to <labelname> if comparison computes to true

Page 36: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction36

Instructions: if_icmp variations

▪ if_icmplt relation using <

▪ if_icmple relation using <=

▪ if_icmpge relation using >=

▪ if_icmpgt relation using >

▪ if_icmpeq relation using ==

▪ if_icmpne relation using !=

Page 37: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction37

Example: LabelsAndJumpsFile: LabelsAndJumps.j

.source noSource

.class public LabelsAndJumps

.super java/lang/Object

.method public static main([Ljava/lang/String;)V

.limit stack 2

.limit locals 2

sipush 10

istore 0 ;store 10 in index 0

goto L_skip_redef

sipush 20

istore 0 ;store 20 to index 0 - skipped

L_skip_redef:

iload 0 ;push value of index 0: 10

sipush 15 ;push 15

if_icmplt L_is_lesser

ldc "greater" ;push string to stack - skipped

goto L_end

L_is_lesser:

ldc "lesser" ;push string to stack

L_end:

; result: string "lesser" on top of stack

return

.end method

Page 38: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction38

Example: LabelsAndJumpsFile: LabelsAndJumps.j

sipush 10

local array

stack

args

Page 39: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction39

Example: LabelsAndJumpsFile: LabelsAndJumps.j

istore 0 local array

stack

10

args

Page 40: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction40

Example: LabelsAndJumpsFile: LabelsAndJumps.j

goto L_skip_redef

sipush 20

istore 0

L_skip_redef:

local array

stack

10

Page 41: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction41

Example: LabelsAndJumpsFile: LabelsAndJumps.j

sipush 20

istore 0

L_skip_redef:

local array

stack

10

Page 42: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction42

Example: LabelsAndJumpsFile: LabelsAndJumps.j

iload 0

local array

stack

10

Page 43: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction43

Example: LabelsAndJumpsFile: LabelsAndJumps.j

sipush 15

local array

stack

10

10

Page 44: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction44

Example: LabelsAndJumpsFile: LabelsAndJumps.j

if_icmplt L_is_lesser

ldc "greater"

goto L_end

L_is_lesser:

ldc "lesser"

L_end:

local array

stack

10

15

10

Page 45: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction45

Example: LabelsAndJumpsFile: LabelsAndJumps.j

ldc "greater"

goto L_end

L_is_lesser:

local array

stack

10

Page 46: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction46

Example: LabelsAndJumpsFile: LabelsAndJumps.j

ldc "lesser"

local array

stack

10

Page 47: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction47

Example: LabelsAndJumpsFile: LabelsAndJumps.j

L_end:

local array

stack

lesser

10

Page 48: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction48

Example: LabelsAndJumpsFile: LabelsAndJumps.j

return

local array

stack

lesser

10

Page 49: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction49

Instructions: field access

▪ Call put-/getfield of object on stack

▪ Call usingputfield <class ID>/<field ID> <type>

getfield <class ID>/<field ID> <type>

▪ Requires value and object on stack

▪ Example▪Jova-field: public int my_field

▪Jasmin-signature: MyClass/my_field I

▪assembly: putfield MyClass/my_field I

Page 50: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction50

Instructions: non-static method calls

▪ Call method of object on stack

▪ Call usinginvokevirtual <class ID>/<method signature>

▪ Requires parameters and object on stack (in correct

order!)

▪ Example▪method: public int myMethod(int a)

▪Jasmin- sig.: MyClass/myMethod(I)I

▪invokation: invokevirtual MyClass/myMethod(I)I

Page 51: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction51

Instructions: print

▪ Based on virtual invokation

▪ How to:

1. Push PrintStream object onto stackgetstatic java/lang/System/out Ljava/io/PrintStream;

2. Push value onto stack (iload, aload, etc.)

3. Invoke matching PrintStream methodinvokevirtual java/io/PrintStream/print(I)V

invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

invokevirtual java/io/PrintStream/print(Z)V

Page 52: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction52

Hints

▪ Try and write some simple Jasmin code yourselves▪ Use aload_0 to get ‘this’ reference

▪ Number your labels

▪ Map Jova/internal variables to locals array indices▪ Instruction swap/dup may be useful in some cases

▪ Use the online documentation to find additional

instructions/explanations

▪ When in doubt: model a problem in Java - compile it -and use javap -c <Class> to decompile the .class

files

Page 53: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction53

References:

▪ Jasmin User Guide:

http://jasmin.sourceforge.net/guide.html

▪ The Structure of the Java Virtual Machine:

https://docs.oracle.com/javase/specs/jvms/se8

/html/jvms-2.html

Page 54: Tutorial 3: Code Generation

Tutorial Code Generation

Compiler Construction54

Questions?