Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
NI-RUN
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Package Registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Štěpánek
NI-RUN
Commits
a4b99815
Commit
a4b99815
authored
1 year ago
by
Michal Štěpánek
Browse files
Options
Downloads
Patches
Plain Diff
Continue with implementation up to method calls (only arrays missing)
parent
ccfbc813
No related branches found
Branches containing commit
No related tags found
1 merge request
!3
Task2 odevzdání
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/bc_interpreter.c
+159
-76
159 additions, 76 deletions
src/bc_interpreter.c
src/bc_interpreter.h
+12
-4
12 additions, 4 deletions
src/bc_interpreter.h
with
171 additions
and
80 deletions
src/bc_interpreter.c
+
159
−
76
View file @
a4b99815
...
...
@@ -46,60 +46,15 @@ void vm_init ( VM * vm, size_t heap_size ) {
void
vm_destroy
(
VM
*
vm
)
{
heap_destroy
(
&
vm
->
heap
);
ostack_destroy
(
&
vm
->
stack
);
for
(
size_t
i
=
0
;
i
<
vm
->
program
.
constant_count
;
++
i
)
{
Constant
constant
=
vm
->
program
.
constant_pool
[
i
];
if
(
constant
.
kind
==
CONSTANT_CLASS
)
free
(
constant
.
class
.
members
);
}
free
(
vm
->
program
.
globals
.
members
);
free
(
vm
->
program
.
constant_pool
);
}
// void * heap_alloc_alligned ( Heap * heap, size_t len, size_t align ) {
// size_t pos = (size_t) heap -> next;
// size_t rem = pos % align;
// if ( rem )
// heap -> next = heap -> next + align - rem;
// if ( heap -> next + len >= heap -> end )
// return NULL;
// void * ret = heap -> next;
// heap -> next += len;
// return ret;
// }
//
// void * heap_alloc ( Heap * heap, size_t len ) {
// size_t pos = (size_t) heap -> next;
// size_t rem = pos % 8;
// if ( rem )
// heap -> next = heap -> next + 8 - rem;
// if ( heap -> next + len >= heap -> end )
// return NULL;
// void * ret = heap -> next;
// heap -> next += len;
// return ret;
// }
//
// void heap_init ( Heap * heap, size_t heap_size ) {
// heap -> begin = (u8*) malloc ( heap_size );
// heap -> next = heap -> begin;
// heap -> end = heap -> begin + heap_size;
// }
//
// void heap_destroy ( Heap * heap ) {
// free ( heap -> begin );
// }
//Value * make_null ( ASTInterpreterState * state ) {
// NullValue * value = heap_alloc ( state -> heap, sizeof (NullValue) );
// *value = (NullValue) { .kind = (Value) { .kind = VALUE_NULL } };
// return (Value*) value;
//}
//
//Value * make_int ( ASTInterpreterState * state, i32 val ) {
// IntValue * value = heap_alloc ( state -> heap, sizeof (IntValue) );
// *value = (IntValue) { .kind = (Value) { .kind = VALUE_INTEGER }, .integer = val };
// return (Value*) value;
//}
//
//Value * make_bool ( ASTInterpreterState * state, bool val ) {
// BoolValue * value = heap_alloc ( state -> heap, sizeof (BoolValue) );
// *value = (BoolValue) { .kind = (Value) { .kind = VALUE_BOOLEAN }, .boolean = val };
// return (Value*) value;
//}
Value
*
alloc_constant
(
VM
*
vm
,
u16
index
)
{
assert
(
vm
->
program
.
constant_count
>
index
);
Constant
constant
=
vm
->
program
.
constant_pool
[
index
];
...
...
@@ -118,6 +73,17 @@ Value * alloc_constant ( VM * vm, u16 index ) {
return
NULL
;
}
ObjectValue
*
create_object
(
VM
*
vm
,
Class
*
class
)
{
ObjectValue
*
object
=
(
ObjectValue
*
)
make_object
(
&
vm
->
heap
,
class
->
member_count
);
Constant
*
pool
=
vm
->
program
.
constant_pool
;
for
(
size_t
i
=
0
;
i
<
class
->
member_count
;
++
i
)
{
Constant
constant
=
pool
[
class
->
members
[
i
]
];
assert
(
constant
.
kind
==
CONSTANT_STRING
);
object
->
members
[
i
]
=
(
SimpleEntry
)
{
.
name
=
constant
.
string
,
.
value
=
NULL
};
}
return
object
;
}
void
print_operand_value
(
Value
*
value
)
{
switch
(
value
->
kind
)
{
case
VALUE_INTEGER
:
...
...
@@ -135,7 +101,7 @@ void print_operand_value ( Value * value ) {
case
VALUE_FUNCTION
:
printf
(
"function"
);
break
;
/*
case
VALUE_ARRAY
:
case
VALUE_ARRAY
:
putchar
(
'['
);
ArrayValue
*
arr
=
(
ArrayValue
*
)
value
;
for
(
i32
i
=
0
;
i
<
arr
->
length
;
++
i
)
{
...
...
@@ -163,7 +129,7 @@ void print_operand_value ( Value * value ) {
print_operand_value
(
obj
->
members
[
i
]
.
value
);
}
putchar
(
')'
);
break
;
*/
break
;
default:
assert
(
false
);
}
...
...
@@ -213,6 +179,7 @@ void print_call ( VM * vm, u16 index, u8 arguments ) {
}
else
putchar
(
c
);
}
free
(
args
);
assert
(
arg
==
arguments
);
}
...
...
@@ -233,6 +200,16 @@ static inline i32 read_i32 ( const u8 * data, size_t * pos ) {
return
bytes
[
3
]
<<
24
|
bytes
[
2
]
<<
16
|
bytes
[
1
]
<<
8
|
bytes
[
0
];
}
static
inline
Class
read_class
(
const
u8
*
data
,
size_t
*
pos
)
{
Class
class
;
u16
elements
=
read_u16
(
data
,
pos
);
class
.
member_count
=
elements
;
class
.
members
=
(
u16
*
)
malloc
(
elements
*
sizeof
(
u16
)
);
for
(
size_t
i
=
0
;
i
<
elements
;
++
i
)
class
.
members
[
i
]
=
read_u16
(
data
,
pos
);
return
class
;
}
void
read_header
(
Str
input
,
size_t
*
pos
)
{
u8
bytes
[
4
];
for
(
size_t
i
=
0
;
i
<
4
;
++
i
)
...
...
@@ -283,6 +260,9 @@ void read_constant_pool ( Program * program, Str input, size_t * pos ) {
constant_pool
[
i
]
=
(
Constant
)
{
.
kind
=
CONSTANT_BOOLEAN
,
.
boolean
=
read_byte
(
input
.
str
,
pos
)
};
// printf ( "%s\n", constant_pool [ i ] . boolean == true ? "true" : "false" );
break
;
case
0x05
:
{
constant_pool
[
i
]
=
(
Constant
)
{
.
kind
=
CONSTANT_CLASS
,
.
class
=
read_class
(
input
.
str
,
pos
)
};
}
default:
// printf ( "unsupported type\n" );
break
;
...
...
@@ -291,10 +271,9 @@ void read_constant_pool ( Program * program, Str input, size_t * pos ) {
program
->
constant_pool
=
constant_pool
;
}
void
read_globals
(
Str
input
,
size_t
*
pos
)
{
u16
elements
=
read_u16
(
input
.
str
,
pos
);
*
pos
+=
elements
;
}
// void read_globals ( Program * program, Str input, size_t * pos ) {
// program -> globals = read_class ( input . str, pos );
// }
void
parse_program
(
Program
*
program
,
Str
input
)
{
// read + check header
...
...
@@ -302,27 +281,48 @@ void parse_program ( Program * program, Str input ) {
read_header
(
input
,
&
pos
);
// read constant pool
read_constant_pool
(
program
,
input
,
&
pos
);
read_globals
(
input
,
&
pos
);
// read globals
program
->
globals
=
read_class
(
input
.
str
,
&
pos
);
// read EP
program
->
entry_point
=
read_u16
(
input
.
str
,
&
pos
);
//printf ("EP: %u\n", program -> entry_point );
}
void
bc_function_call
(
VM
*
vm
,
u8
arguments
)
{
// assert ( index < vm -> program . constant_count );
// assert ( vm -> program . constant_pool [ index ] . kind == CONSTANT_FUNCTION );
void
bc_function_call
(
VM
*
vm
,
u8
arguments
,
bool
is_function
,
Str
*
name
)
{
Value
*
tmp
[
256
];
for
(
size_t
i
=
0
;
i
<
arguments
;
++
i
)
tmp
[
i
]
=
ostack_pop
(
&
vm
->
stack
);
Value
*
fvalue
=
ostack_pop
(
&
vm
->
stack
);
assert
(
fvalue
->
kind
==
VALUE_FUNCTION
);
ConstantFunction
function
=
((
CFunctionValue
*
)
fvalue
)
->
function
;
arguments
=
is_function
?
arguments
:
arguments
-
1
;
for
(
size_t
i
=
arguments
;
i
>
0
;
++
i
)
tmp
[
i
-
1
]
=
ostack_pop
(
&
vm
->
stack
);
Value
*
callee
=
ostack_pop
(
&
vm
->
stack
);
ConstantFunction
function
;
if
(
is_function
)
{
assert
(
callee
->
kind
==
VALUE_FUNCTION
);
function
=
((
CFunctionValue
*
)
callee
)
->
function
;
}
else
{
Value
*
field
=
*
get_object_field
(
callee
,
*
name
);
while
(
!
field
)
{
callee
=
((
ObjectValue
*
)
callee
)
->
extends
;
if
(
callee
->
kind
!=
VALUE_OBJECT
)
break
;
field
=
*
get_object_field
(
callee
,
*
name
);
}
if
(
!
field
)
{
Value
*
result
=
try_operator
(
&
vm
->
heap
,
callee
,
tmp
,
arguments
,
name
);
assert
(
result
);
ostack_push
(
&
vm
->
stack
,
result
);
}
assert
(
field
->
kind
==
VALUE_FUNCTION
);
function
=
((
CFunctionValue
*
)
field
)
->
function
;
}
size_t
local_count
=
function
.
parameters
+
function
.
locals
;
Frame
*
new_frame
=
(
Frame
*
)
malloc
(
sizeof
(
Frame
)
+
local_count
*
sizeof
(
Value
*
)
);
new_frame
->
prev
=
vm
->
local_frame
;
new_frame
->
return_ip
=
++
(
vm
->
instruction_pointer
)
;
new_frame
->
return_ip
=
vm
->
instruction_pointer
;
vm
->
local_frame
=
new_frame
;
assert
(
arguments
+
1
==
function
.
parameters
);
new_frame
->
locals
[
0
]
=
make_null
(
&
vm
->
heap
);
if
(
is_function
)
new_frame
->
locals
[
0
]
=
make_null
(
&
vm
->
heap
);
else
new_frame
->
locals
[
0
]
=
callee
;
for
(
size_t
i
=
1
;
i
<=
arguments
;
++
i
)
new_frame
->
locals
[
i
]
=
tmp
[
i
-
1
];
for
(
size_t
i
=
arguments
+
1
;
i
<
local_count
;
++
i
)
...
...
@@ -332,29 +332,82 @@ void bc_function_call ( VM * vm, u8 arguments ) {
opcode
=
read_byte
(
function
.
start
,
&
vm
->
instruction_pointer
);
switch
(
opcode
)
{
case
0x00
:
//printf ("drop\n");
//
printf ("drop\n");
ostack_pop
(
&
vm
->
stack
);
break
;
case
0x01
:
{
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
//printf ("constant %u\n", index);
//
printf ("constant %u\n", index);
ostack_push
(
&
vm
->
stack
,
alloc_constant
(
vm
,
index
)
);
break
;
}
case
0x02
:
{
//printf ("print\n");
//
printf ("print\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
u8
arguments
=
read_byte
(
function
.
start
,
&
vm
->
instruction_pointer
);
print_call
(
vm
,
index
,
arguments
);
ostack_push
(
&
vm
->
stack
,
make_null
(
&
vm
->
heap
)
);
break
;
}
case
0x04
:
{
// printf ("object\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
Constant
constant
=
vm
->
program
.
constant_pool
[
index
];
assert
(
constant
.
kind
==
CONSTANT_CLASS
);
assert
(
constant
.
class
.
member_count
<
vm
->
stack
.
size
);
ObjectValue
*
obj
=
create_object
(
vm
,
&
constant
.
class
);
for
(
size_t
i
=
obj
->
member_cnt
;
i
>
0
;
--
i
)
obj
->
members
[
i
-
1
]
.
value
=
ostack_pop
(
&
vm
->
stack
);
obj
->
extends
=
ostack_pop
(
&
vm
->
stack
);
ostack_push
(
&
vm
->
stack
,
(
Value
*
)
obj
);
break
;
}
case
0x05
:
{
// printf ("get field\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
vm
->
program
.
constant_count
);
Constant
name
=
vm
->
program
.
constant_pool
[
index
];
assert
(
name
.
kind
==
CONSTANT_STRING
);
Value
*
object
=
ostack_pop
(
&
vm
->
stack
);
assert
(
object
->
kind
==
VALUE_OBJECT
);
Value
**
field
=
get_object_field
(
object
,
name
.
string
);
assert
(
field
);
ostack_push
(
&
vm
->
stack
,
*
field
);
break
;
}
case
0x06
:
{
// printf ("set field\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
vm
->
program
.
constant_count
);
Constant
name
=
vm
->
program
.
constant_pool
[
index
];
assert
(
name
.
kind
==
CONSTANT_STRING
);
Value
*
value
=
ostack_pop
(
&
vm
->
stack
);
Value
*
object
=
ostack_pop
(
&
vm
->
stack
);
assert
(
object
->
kind
==
VALUE_OBJECT
);
Value
**
field
=
get_object_field
(
object
,
name
.
string
);
assert
(
field
);
*
field
=
value
;
ostack_push
(
&
vm
->
stack
,
value
);
break
;
}
case
0x07
:
{
// printf ("method call\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
u8
arguments
=
read_byte
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
vm
->
program
.
constant_count
);
Constant
name
=
vm
->
program
.
constant_pool
[
index
];
assert
(
name
.
kind
==
CONSTANT_STRING
);
bc_function_call
(
vm
,
arguments
,
false
,
&
name
.
string
);
break
;
}
case
0x08
:
{
// printf ("function call\n");
u8
arguments
=
read_byte
(
function
.
start
,
&
vm
->
instruction_pointer
);
bc_function_call
(
vm
,
arguments
);
bc_function_call
(
vm
,
arguments
,
true
,
NULL
);
break
;
}
case
0x09
:
{
// printf ("set local\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
local_count
);
assert
(
vm
->
stack
.
size
);
...
...
@@ -362,12 +415,36 @@ void bc_function_call ( VM * vm, u8 arguments ) {
break
;
}
case
0x0A
:
{
// printf ("get local\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
local_count
);
ostack_push
(
&
vm
->
stack
,
new_frame
->
locals
[
index
]
);
break
;
}
case
0x0B
:
{
// printf ("set global\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
vm
->
program
.
constant_count
);
Constant
name
=
vm
->
program
.
constant_pool
[
index
];
assert
(
name
.
kind
==
CONSTANT_STRING
);
Value
**
field
=
get_object_field
(
vm
->
globals
,
name
.
string
);
assert
(
field
);
*
field
=
ostack_top
(
&
vm
->
stack
);
break
;
}
case
0x0C
:
{
// printf ("get global\n");
u16
index
=
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
index
<
vm
->
program
.
constant_count
);
Constant
name
=
vm
->
program
.
constant_pool
[
index
];
assert
(
name
.
kind
==
CONSTANT_STRING
);
Value
**
field
=
get_object_field
(
vm
->
globals
,
name
.
string
);
assert
(
field
);
ostack_push
(
&
vm
->
stack
,
*
field
);
break
;
}
case
0x0D
:
{
// printf ("cond\n");
i16
offset
=
(
i16
)
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
(
i32
)
vm
->
instruction_pointer
>=
offset
&&
vm
->
instruction_pointer
+
offset
<
function
.
len
);
Value
*
cond
=
ostack_top
(
&
vm
->
stack
);
...
...
@@ -376,12 +453,14 @@ void bc_function_call ( VM * vm, u8 arguments ) {
break
;
}
case
0x0E
:
{
// printf ("jump\n");
i16
offset
=
(
i16
)
read_u16
(
function
.
start
,
&
vm
->
instruction_pointer
);
assert
(
(
i32
)
vm
->
instruction_pointer
>=
offset
&&
vm
->
instruction_pointer
+
offset
<
function
.
len
);
vm
->
instruction_pointer
+=
offset
;
break
;
}
case
0x0F
:
{
// printf ("ret\n");
Frame
*
tmp
=
vm
->
local_frame
;
vm
->
local_frame
=
tmp
->
prev
;
vm
->
instruction_pointer
=
tmp
->
return_ip
;
...
...
@@ -389,7 +468,7 @@ void bc_function_call ( VM * vm, u8 arguments ) {
return
;
}
default:
//printf ( "%d\n", opcode );
//
printf ( "%d\n", opcode );
assert
(
false
);
}
}
...
...
@@ -398,7 +477,11 @@ void bc_function_call ( VM * vm, u8 arguments ) {
int
vm_interpret
(
VM
*
vm
,
Str
input
)
{
parse_program
(
&
vm
->
program
,
input
);
ostack_push
(
&
vm
->
stack
,
alloc_constant
(
vm
,
vm
->
program
.
entry_point
)
);
bc_function_call
(
vm
,
0
);
ObjectValue
*
obj
=
create_object
(
vm
,
&
vm
->
program
.
globals
);
for
(
size_t
i
=
0
;
i
<
obj
->
member_cnt
;
++
i
)
obj
->
members
[
i
]
.
value
=
make_null
(
&
vm
->
heap
);
vm
->
globals
=
(
Value
*
)
obj
;
bc_function_call
(
vm
,
0
,
true
,
NULL
);
//Constant start = vm -> program . constant_pool [ vm -> program . entry_point ];
//u8 opcode;
...
...
This diff is collapsed.
Click to expand it.
src/bc_interpreter.h
+
12
−
4
View file @
a4b99815
...
...
@@ -13,11 +13,17 @@ typedef enum {
CONSTANT_NULL,
CONSTANT_STRING,
CONSTANT_FUNCTION,
CONSTANT_CLASS
// VALUE_ARRAY,
// VALUE_OBJECT,
// VALUE_INVALID
} ConstantType;
typedef struct Class {
u16 member_count;
u16 * members;
} Class;
typedef struct Constant {
ConstantType kind;
union {
...
...
@@ -25,13 +31,14 @@ typedef struct Constant {
bool boolean;
Str string;
ConstantFunction function;
Class class;
};
} Constant;
typedef struct Program {
u16 constant_count;
Constant * constant_pool;
//uint32_t *
globals;
Class
globals;
//size_t entry_point;
u16 entry_point;
} Program;
...
...
@@ -58,7 +65,7 @@ typedef struct VM {
Program program;
Heap heap;
OperandStack stack;
//FrameStack fstack
;
Value * globals
;
Frame * local_frame;
size_t instruction_pointer;
} VM;
...
...
@@ -77,16 +84,17 @@ void vm_destroy ( VM * vm );
//inline u8 read_byte ( Str str, size_t * pos );
Value * alloc_constant ( VM * vm, u16 index );
ObjectValue * create_object ( VM * vm, Class * class );
void print_operand_value ( Value * value );
void print_call ( VM * vm, u16 index, u8 arguments );
void read_header ( Str input, size_t * pos );
void read_constant_pool ( Program * program, Str input, size_t * pos );
void read_globals ( Str input, size_t * pos );
//
void read_globals (
Program * program,
Str input, size_t * pos );
void parse_program ( Program * program, Str input );
void bc_function_call ( VM * vm, u8 arguments );
void bc_function_call ( VM * vm, u8 arguments
, bool is_function, Str * name
);
//void bc_intepret ( VM * vm, Str input, size_t & offset );
int vm_interpret ( VM * vm, Str input );
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment