Lecture 9: Programming Language Semantics
Programming Languages Course
Aarne Ranta (aarne@cs.chalmers.se)
%!target:html
%!postproc(html): #NEW
%!postproc(html): #HR
%!postproc(html): #sub1 1
%!postproc(html): #subn n
%!postproc(html): #subn1 n-1
Book:
#NEW
==Plan==
What is semantics?
What is meaning?
Operational semantics: small-step
Operational semantics: big-step
Abstract interprerations
Up to here, we follow [another set of slides ./proglang-09.pdf] with a nice
notation and lay-out, by Ulf Norell, pp. 1-19.
Next time: from semantics to interpreter implementation
This time: case study on small-step semantics: JVM
#NEW
==Java bytecode interpretation==
Byte code, virtual machine code - simpler than high-level source code.
Example: JVM (Java Virtual Machine)
```
bipush n -- push byte constant n
iadd -- add two integers; pop the operands and push the result
imul -- multiply two integers; pop the operands and push the result
istore x -- store value in stack address x and pop it
iload x -- push value to stack address x
dup -- duplicate the top of the stack
invokestatic -- call a function with parameters from the top of the
stack, pop the parameters and push the value
```
Java is compiled to JVM (next lecture).
JVM is interpreted, or compiled to native machine code by JIT
(Just In Time compilation).
Most "interpreted languages" are actually compiled to byte code.
Exception: Ruby.
Example use of ``invokestatic``, generated from ``printInt(5)``:
```
bipush 5
invokestatic runtime/iprint(I)V
```
The type ``(I)V`` tells e.g. how many values to pop.
#NEW
==JVM interpreter==
Environment: **local variable storage** and a **stack** holding values
Primitive actions:
- **store** value in place #i in local storage
- **load** value from place #i in local storage
- **push** a value to the stack
- **pop** a value from the stack
Example execution: ``5 * (6 + 7)``
```
bipush 5 ; bipush 6 ; bipush 7 ; iadd ; imul
-- -- -- -- --
5 5 5 5 65
6 6 13
7
```
#NEW
==Local variables in JVM==
The compiler assigns local storage addresses to variables (lecture 11).
```
int i ; ; reserve address 0 for i
i = 9 ; bipush 9
istore 0
int j = i + 3 ; ; reserve address 1 for j
iload 0
bipush 3
iadd
istore 1
```
#NEW
==Semantics of JVM==
Naturally expressed using small-step semantics. The environment has storage V and stack S.
The rules work on instructions, executed one at a time.
```
-->
-->
-->
-->
-->
-->
-->
```
Notation used:
|| Notation | Explanation ||
| ```` | instruction ``c``, with storage ``V`` and stack ``S`` |
| ``S.v`` | stack with all values in ``S`` plus ``v`` on the top |
| ``V(i)`` | the value at position ``i`` in storage ``V`` |
| ``V(i:=v)`` | storage ``V`` with value ``v`` put into position ``i`` |
#NEW
==Dealing with jumps==
JVM does not always continue with the next instruction, but there can be jumps.
Example (my first BASIC program):
```
BEGIN:
bipush 66
invokestatic runtime/iprint(I)V
goto BEGIN
```
To give semantics to the ``goto`` instruction, we have to add the
code ``C`` to the environment.
We denote by ``C(p)`` the instruction at position ``p`` in ``C``.
```
-->
```
Question: How do we now express rules for the "ordinary" instructions?
```
-->
```
Answer: we add a code pointer ``P`` to the environment:
```
-->
-->
```