load class files from Java

This commit is contained in:
Zack Buhman 2025-01-02 08:46:49 -06:00
parent c82d5a59d9
commit 9090f266cd
15 changed files with 330 additions and 21 deletions

View File

@ -112,6 +112,7 @@ static int32_t class_resolver_create_fields_hash_table(int class_hash_table_leng
int fields_hash_table_length = hash_table_next_power_of_two(class_entry->class_file->fields_count * 2);
uint32_t fields_hash_table_size = (sizeof (struct hash_table_entry)) * fields_hash_table_length;
struct hash_table_entry * fields_hash_table = malloc_class_arena(fields_hash_table_size);
hash_table_init(fields_hash_table_length, fields_hash_table);
int static_index = 0;
@ -159,6 +160,8 @@ static void class_resolver_create_methods_hash_table(struct class_entry * class_
int methods_hash_table_length = hash_table_next_power_of_two(class_file->methods_count * 2);
uint32_t methods_hash_table_size = (sizeof (struct hash_table_entry)) * methods_hash_table_length;
struct hash_table_entry * methods_hash_table = malloc_class_arena(methods_hash_table_size);
hash_table_init(methods_hash_table_length, methods_hash_table);
for (int i = 0; i < class_file->methods_count; i++) {
u2 name_index = class_file->methods[i].name_index;
struct constant * name_constant = &class_file->constant_pool[name_index - 1];
@ -215,6 +218,8 @@ struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** buff
int class_hash_table_length = hash_table_next_power_of_two(hash_table_next_power_of_two(length * 2));
uint32_t class_hash_table_size = (sizeof (struct hash_table_entry)) * class_hash_table_length;
struct hash_table_entry * class_hash_table = malloc_class_arena(class_hash_table_size);
hash_table_init(class_hash_table_length, class_hash_table);
uint32_t class_entry_size = (sizeof (struct class_entry)) * length;
struct class_entry * class_entry = malloc_class_arena(class_entry_size);
@ -233,7 +238,7 @@ struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** buff
assert(class_name_constant->tag == CONSTANT_Utf8);
debugf("hash table entry for class: ");
print_utf8_string(class_name_constant);
debugf("\n");
debugf(" %p\n", &class_entry[i]);
hash_table_add(class_hash_table_length,
class_hash_table,

View File

@ -1274,6 +1274,7 @@ void op_invokevirtual(struct vm * vm, uint32_t index)
int32_t * objectref = (int32_t *)operand_stack_peek_u32(vm->current_frame, nargs + 1);
assert(objectref != nullptr);
struct class_entry * class_entry = (struct class_entry *)objectref[0];
debugf("class_entry: %p\n", class_entry);
struct method_entry method_entry =
class_resolver_lookup_method_from_interfacemethodref_index(vm->class_hash_table.length,

View File

@ -304,7 +304,7 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str
hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"getResource", method_name_constant->utf8.length);
if (getresource) {
assert(nargs == 1);
assert(return_type == '[');
assert(return_type == 'I');
uint32_t value = java_misc_resource_getresource_1(args);
operand_stack_push_u32(vm->current_frame, value);
return;
@ -333,6 +333,30 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str
}
}
int jvm_internal_loader_length = 19;
bool jvm_internal_loader =
class_name_constant->utf8.length == jvm_internal_loader_length &&
hash_table_key_equal(class_name_constant->utf8.bytes, (const uint8_t *)"jvm/internal/Loader", class_name_constant->utf8.length);
if (jvm_internal_loader) {
if (method_name_constant->utf8.length == 4) {
if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"load", 4)) {
assert(nargs == 1);
assert(return_type == 'V');
native_jvm_internal_loader_load(args);
return;
}
}
if (method_name_constant->utf8.length == 9) {
if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"getBuffer", 9)) {
assert(nargs == 0);
assert(return_type == 'I');
uint32_t value = native_jvm_internal_loader_getbuffer();
operand_stack_push_u32(vm->current_frame, value);
return;
}
}
}
assert(false);
}
@ -533,7 +557,7 @@ void vm_execute(struct vm * vm)
}
}
void vm_start(int class_hash_table_length,
struct vm * vm_start(int class_hash_table_length,
struct hash_table_entry * class_hash_table,
const uint8_t * main_class_name,
int main_class_name_length)
@ -559,7 +583,7 @@ void vm_start(int class_hash_table_length,
method_descriptor_length);
assert(method_info != nullptr);
struct vm vm;
static struct vm vm;
vm.class_hash_table.entry = class_hash_table;
vm.class_hash_table.length = class_hash_table_length;
@ -583,5 +607,6 @@ void vm_start(int class_hash_table_length,
entry_frame->operand_stack_ix = 0;
vm_static_method_call(&vm, class_entry, method_info);
vm_execute(&vm);
return &vm;
}

View File

@ -160,7 +160,7 @@ void vm_special_method_call(struct vm * vm, struct class_entry * class_entry, st
void vm_static_method_call(struct vm * vm, struct class_entry * class_entry, struct method_info * method_info);
void vm_method_return(struct vm * vm);
void vm_execute(struct vm * vm);
void vm_start(int class_hash_table_length,
struct vm * vm_start(int class_hash_table_length,
struct hash_table_entry * class_hash_table,
const uint8_t * main_class_name,
int main_class_name_length);

View File

@ -64,6 +64,8 @@ void hash_table_add(int hash_table_length,
if (e->key != nullptr) {
// allocate e from overflow
e->next = malloc_class_arena((sizeof (struct hash_table_entry)));
e->next->key = nullptr;
e->next->next = nullptr;
e = e->next;
}
@ -135,6 +137,8 @@ void hash_table_add2(int hash_table_length,
if (e->key != nullptr) {
// allocate e from overflow
e->next = malloc_class_arena((sizeof (struct hash_table_entry)));
e->next->key = nullptr;
e->next->next = nullptr;
e = e->next;
}

View File

@ -4,6 +4,8 @@
#include "class_resolver.h"
#include "frame.h"
#include "printf.h"
#include "malloc.h"
#include "memory_allocator.h"
#include "sh7091_scif.h"
@ -26,13 +28,17 @@ void main()
scif_character(main_class[i]);
scif_character('\n');
memory_reset_free_list();
malloc_class_arena_reset();
int class_hash_table_length;
struct hash_table_entry * class_hash_table = class_resolver_load_from_buffers(class_file_buffers,
class_file_buffers_length,
&class_hash_table_length);
vm_start(class_hash_table_length,
struct vm * vm = vm_start(class_hash_table_length,
class_hash_table,
main_class,
main_class_length);
vm_execute(vm);
}

View File

@ -6,6 +6,8 @@
#include "class_resolver.h"
#include "string.h"
#include "file.h"
#include "malloc.h"
#include "memory_allocator.h"
static struct hash_table_entry * load_from_filenames(const char * filenames[], int length, int * hash_table_length)
{
@ -17,6 +19,9 @@ static struct hash_table_entry * load_from_filenames(const char * filenames[], i
buffers[i] = file_read(filenames[i], &file_size[i]);
}
memory_reset_free_list();
malloc_class_arena_reset();
struct hash_table_entry * class_hash_table = class_resolver_load_from_buffers((const uint8_t **)buffers,
length,
hash_table_length);
@ -42,8 +47,11 @@ int main(int argc, const char * argv[])
int class_hash_table_length;
struct hash_table_entry * class_hash_table = load_from_filenames(class_filenames, num_class_filenames, &class_hash_table_length);
vm_start(class_hash_table_length,
debugf("vm_start\n");
struct vm * vm = vm_start(class_hash_table_length,
class_hash_table,
main_class,
main_class_length);
vm_execute(vm);
}

View File

@ -15,6 +15,11 @@ struct arena class_arena = {
.ix = 0,
};
void malloc_class_arena_reset()
{
class_arena.ix = 0;
}
void * malloc_class_arena(uint32_t size)
{
if (size == 0)

View File

@ -2,4 +2,5 @@
#include <stdint.h>
void malloc_class_arena_reset();
void * malloc_class_arena(uint32_t size);

View File

@ -1,5 +1,10 @@
#include "native.h"
#include "printf.h"
#include "string.h"
#include "malloc.h"
#include "memory_allocator.h"
#include "class_resolver.h"
#include "frame.h"
void native_java_io_printstream_write(uint32_t * arrayref)
{
@ -128,3 +133,35 @@ uint32_t native_java_misc_memory_isbigendian()
{
return (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__);
}
static uint8_t loader_buffer[0x100000];
uint32_t native_jvm_internal_loader_getbuffer()
{
return (uint32_t)&loader_buffer[0];
}
extern struct vm vm;
void native_jvm_internal_loader_load(uint32_t * args)
{
uint32_t * arrayref = (uint32_t *)args[0];
int32_t buffers_length = (int32_t)arrayref[0];
const uint8_t ** buffers = (const uint8_t **)&arrayref[1];
const uint8_t * main_class = (const uint8_t *)"Main";
int main_class_length = string_length((const char *)main_class);
memory_reset_free_list();
malloc_class_arena_reset();
int class_hash_table_length;
struct hash_table_entry * class_hash_table = class_resolver_load_from_buffers(buffers,
buffers_length,
&class_hash_table_length);
struct vm * vm = vm_start(class_hash_table_length,
class_hash_table,
main_class,
main_class_length);
}

View File

@ -16,3 +16,5 @@ uint32_t native_java_lang_math_sin_1(uint32_t * args);
uint32_t native_java_lang_math_cos_1(uint32_t * args);
uint32_t java_misc_resource_getresource_1(uint32_t * args);
uint32_t native_java_misc_memory_isbigendian();
uint32_t native_jvm_internal_loader_getbuffer();
void native_jvm_internal_loader_load(uint32_t * args);

24
class_bytes.py Normal file
View File

@ -0,0 +1,24 @@
filenames = [
"Main.class",
"java/lang/Object.class",
"java/io/PrintStream.class",
]
import struct
def sign_extend(value, bits):
sign_bit = 1 << (bits - 1)
return (value & (sign_bit - 1)) - (value & sign_bit)
def print_bytearray(buf):
print("new byte[] {")
for i in range(len(buf)):
print(f"{sign_extend(buf[i], 8)},", end=' ')
if i % 16 == 15:
print()
print("};")
for filename in filenames:
with open(filename, 'rb') as f:
buf = f.read()
print_bytearray(buf)

View File

@ -4,5 +4,5 @@ public class Resource {
private Resource() {
}
public static native int[] getResource(String name);
public static native int getResource(String name);
}

10
jvm/internal/Loader.java Normal file
View File

@ -0,0 +1,10 @@
package jvm.internal;
public class Loader {
private Loader() {
}
public static native int getBuffer();
public static native void load(int[] buffers);
}

181
p/TestLoader.java Normal file
View File

@ -0,0 +1,181 @@
package p;
import jvm.internal.Loader;
import java.misc.Memory;
class TestLoader {
static byte[][] buffers;
static {
buffers = new byte[3][];
buffers[0] = new byte[] {
-54, -2, -70, -66, 0, 0, 0, 52, 0, 20, 10, 0, 2, 0, 3, 7,
0, 4, 12, 0, 5, 0, 6, 1, 0, 16, 106, 97, 118, 97, 47, 108,
97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 6, 60, 105, 110,
105, 116, 62, 1, 0, 3, 40, 41, 86, 10, 0, 8, 0, 9, 7, 0,
10, 12, 0, 11, 0, 12, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111,
47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 1, 0, 5, 119,
114, 105, 116, 101, 1, 0, 5, 40, 91, 66, 41, 86, 7, 0, 14, 1,
0, 4, 77, 97, 105, 110, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15,
76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1,
0, 4, 109, 97, 105, 110, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70,
105, 108, 101, 1, 0, 9, 77, 97, 105, 110, 46, 106, 97, 118, 97, 0,
32, 0, 13, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0,
6, 0, 1, 0, 15, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0,
5, 42, -73, 0, 1, -79, 0, 0, 0, 1, 0, 16, 0, 0, 0, 6,
0, 1, 0, 0, 0, 3, 0, 9, 0, 17, 0, 6, 0, 1, 0, 15,
0, 0, 0, 114, 0, 4, 0, 1, 0, 0, 0, 82, 16, 13, -68, 8,
89, 3, 16, 104, 84, 89, 4, 16, 101, 84, 89, 5, 16, 108, 84, 89,
6, 16, 108, 84, 89, 7, 16, 111, 84, 89, 8, 16, 32, 84, 89, 16,
6, 16, 119, 84, 89, 16, 7, 16, 111, 84, 89, 16, 8, 16, 114, 84,
89, 16, 9, 16, 108, 84, 89, 16, 10, 16, 100, 84, 89, 16, 11, 16,
33, 84, 89, 16, 12, 16, 10, 84, 75, 42, -72, 0, 7, -79, 0, 0,
0, 1, 0, 16, 0, 0, 0, 14, 0, 3, 0, 0, 0, 5, 0, 77,
0, 6, 0, 81, 0, 7, 0, 1, 0, 18, 0, 0, 0, 2, 0, 19,
};
buffers[1] = new byte[] {
-54, -2, -70, -66, 0, 0, 0, 52, 0, 13, 8, 0, 2, 1, 0, 6,
79, 98, 106, 101, 99, 116, 7, 0, 4, 1, 0, 16, 106, 97, 118, 97,
47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 6, 60,
105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111,
100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84,
97, 98, 108, 101, 1, 0, 8, 116, 111, 83, 116, 114, 105, 110, 103, 1,
0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83,
116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70,
105, 108, 101, 1, 0, 11, 79, 98, 106, 101, 99, 116, 46, 106, 97, 118,
97, 0, 33, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0,
5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 25, 0, 0, 0, 1, 0,
0, 0, 1, -79, 0, 0, 0, 1, 0, 8, 0, 0, 0, 6, 0, 1,
0, 0, 0, 4, 0, 1, 0, 9, 0, 10, 0, 1, 0, 7, 0, 0,
0, 27, 0, 1, 0, 1, 0, 0, 0, 3, 18, 1, -80, 0, 0, 0,
1, 0, 8, 0, 0, 0, 6, 0, 1, 0, 0, 0, 7, 0, 1, 0,
11, 0, 0, 0, 2, 0, 12,
};
buffers[2] = new byte[] {
-54, -2, -70, -66, 0, 0, 0, 52, 0, 61, 10, 0, 2, 0, 3, 7,
0, 4, 12, 0, 5, 0, 6, 1, 0, 16, 106, 97, 118, 97, 47, 108,
97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 6, 60, 105, 110,
105, 116, 62, 1, 0, 3, 40, 41, 86, 9, 0, 8, 0, 9, 7, 0,
10, 12, 0, 11, 0, 12, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111,
47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 1, 0, 7, 110,
101, 119, 108, 105, 110, 101, 1, 0, 2, 91, 66, 10, 0, 14, 0, 15,
7, 0, 16, 12, 0, 17, 0, 18, 1, 0, 16, 106, 97, 118, 97, 47,
108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 1, 0, 8, 103, 101,
116, 66, 121, 116, 101, 115, 1, 0, 4, 40, 41, 91, 66, 10, 0, 8,
0, 20, 12, 0, 21, 0, 22, 1, 0, 5, 119, 114, 105, 116, 101, 1,
0, 5, 40, 91, 66, 41, 86, 10, 0, 14, 0, 24, 12, 0, 25, 0,
26, 1, 0, 7, 118, 97, 108, 117, 101, 79, 102, 1, 0, 21, 40, 90,
41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105,
110, 103, 59, 10, 0, 8, 0, 28, 12, 0, 21, 0, 29, 1, 0, 21,
40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105,
110, 103, 59, 41, 86, 10, 0, 14, 0, 31, 12, 0, 25, 0, 32, 1,
0, 21, 40, 67, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
83, 116, 114, 105, 110, 103, 59, 10, 0, 14, 0, 34, 12, 0, 25, 0,
35, 1, 0, 21, 40, 73, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110,
103, 47, 83, 116, 114, 105, 110, 103, 59, 10, 0, 14, 0, 37, 12, 0,
25, 0, 38, 1, 0, 21, 40, 74, 41, 76, 106, 97, 118, 97, 47, 108,
97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 10, 0, 14, 0, 40,
12, 0, 25, 0, 41, 1, 0, 21, 40, 70, 41, 76, 106, 97, 118, 97,
47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 10, 0, 14,
0, 43, 12, 0, 25, 0, 44, 1, 0, 21, 40, 68, 41, 76, 106, 97,
118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 10,
0, 14, 0, 46, 12, 0, 25, 0, 47, 1, 0, 38, 40, 76, 106, 97,
118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 41,
76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110,
103, 59, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101,
78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 5, 112, 114,
105, 110, 116, 1, 0, 4, 40, 90, 41, 86, 1, 0, 4, 40, 67, 41,
86, 1, 0, 4, 40, 73, 41, 86, 1, 0, 4, 40, 74, 41, 86, 1,
0, 4, 40, 70, 41, 86, 1, 0, 4, 40, 68, 41, 86, 1, 0, 21,
40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101,
99, 116, 59, 41, 86, 1, 0, 7, 112, 114, 105, 110, 116, 108, 110, 1,
0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 80,
114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 46, 106, 97, 118, 97, 0,
33, 0, 8, 0, 2, 0, 0, 0, 1, 0, 18, 0, 11, 0, 12, 0,
0, 0, 20, 0, 1, 0, 5, 0, 6, 0, 1, 0, 48, 0, 0, 0,
49, 0, 5, 0, 1, 0, 0, 0, 17, 42, -73, 0, 1, 42, 4, -68,
8, 89, 3, 16, 10, 84, -75, 0, 7, -79, 0, 0, 0, 1, 0, 49,
0, 0, 0, 14, 0, 3, 0, 0, 0, 8, 0, 4, 0, 11, 0, 16,
0, 9, 1, 9, 0, 21, 0, 22, 0, 0, 0, 9, 0, 21, 0, 29,
0, 1, 0, 48, 0, 0, 0, 36, 0, 1, 0, 1, 0, 0, 0, 8,
42, -74, 0, 13, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0,
0, 10, 0, 2, 0, 0, 0, 16, 0, 7, 0, 17, 0, 1, 0, 50,
0, 22, 0, 1, 0, 48, 0, 0, 0, 33, 0, 1, 0, 2, 0, 0,
0, 5, 43, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0,
10, 0, 2, 0, 0, 0, 20, 0, 4, 0, 21, 0, 1, 0, 50, 0,
51, 0, 1, 0, 48, 0, 0, 0, 36, 0, 1, 0, 2, 0, 0, 0,
8, 27, -72, 0, 23, -72, 0, 27, -79, 0, 0, 0, 1, 0, 49, 0,
0, 0, 10, 0, 2, 0, 0, 0, 24, 0, 7, 0, 25, 0, 1, 0,
50, 0, 52, 0, 1, 0, 48, 0, 0, 0, 36, 0, 1, 0, 2, 0,
0, 0, 8, 27, -72, 0, 30, -72, 0, 27, -79, 0, 0, 0, 1, 0,
49, 0, 0, 0, 10, 0, 2, 0, 0, 0, 28, 0, 7, 0, 29, 0,
1, 0, 50, 0, 53, 0, 1, 0, 48, 0, 0, 0, 36, 0, 1, 0,
2, 0, 0, 0, 8, 27, -72, 0, 33, -72, 0, 27, -79, 0, 0, 0,
1, 0, 49, 0, 0, 0, 10, 0, 2, 0, 0, 0, 32, 0, 7, 0,
33, 0, 1, 0, 50, 0, 54, 0, 1, 0, 48, 0, 0, 0, 36, 0,
2, 0, 3, 0, 0, 0, 8, 31, -72, 0, 36, -72, 0, 27, -79, 0,
0, 0, 1, 0, 49, 0, 0, 0, 10, 0, 2, 0, 0, 0, 36, 0,
7, 0, 37, 0, 1, 0, 50, 0, 55, 0, 1, 0, 48, 0, 0, 0,
36, 0, 1, 0, 2, 0, 0, 0, 8, 35, -72, 0, 39, -72, 0, 27,
-79, 0, 0, 0, 1, 0, 49, 0, 0, 0, 10, 0, 2, 0, 0, 0,
40, 0, 7, 0, 41, 0, 1, 0, 50, 0, 56, 0, 1, 0, 48, 0,
0, 0, 36, 0, 2, 0, 3, 0, 0, 0, 8, 39, -72, 0, 42, -72,
0, 27, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0, 10, 0, 2, 0,
0, 0, 44, 0, 7, 0, 45, 0, 1, 0, 50, 0, 57, 0, 1, 0,
48, 0, 0, 0, 36, 0, 1, 0, 2, 0, 0, 0, 8, 43, -72, 0,
45, -72, 0, 27, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0, 10, 0,
2, 0, 0, 0, 48, 0, 7, 0, 49, 0, 1, 0, 58, 0, 6, 0,
1, 0, 48, 0, 0, 0, 36, 0, 1, 0, 1, 0, 0, 0, 8, 42,
-76, 0, 7, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0,
10, 0, 2, 0, 0, 0, 52, 0, 7, 0, 53, 0, 1, 0, 58, 0,
22, 0, 1, 0, 48, 0, 0, 0, 44, 0, 1, 0, 2, 0, 0, 0,
12, 43, -72, 0, 19, 42, -76, 0, 7, -72, 0, 19, -79, 0, 0, 0,
1, 0, 49, 0, 0, 0, 14, 0, 3, 0, 0, 0, 56, 0, 4, 0,
57, 0, 11, 0, 58, 0, 1, 0, 58, 0, 51, 0, 1, 0, 48, 0,
0, 0, 47, 0, 1, 0, 2, 0, 0, 0, 15, 27, -72, 0, 23, -72,
0, 27, 42, -76, 0, 7, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49,
0, 0, 0, 14, 0, 3, 0, 0, 0, 61, 0, 7, 0, 62, 0, 14,
0, 63, 0, 1, 0, 58, 0, 52, 0, 1, 0, 48, 0, 0, 0, 47,
0, 1, 0, 2, 0, 0, 0, 15, 27, -72, 0, 30, -72, 0, 27, 42,
-76, 0, 7, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0,
14, 0, 3, 0, 0, 0, 66, 0, 7, 0, 67, 0, 14, 0, 68, 0,
1, 0, 58, 0, 53, 0, 1, 0, 48, 0, 0, 0, 47, 0, 1, 0,
2, 0, 0, 0, 15, 27, -72, 0, 33, -72, 0, 27, 42, -76, 0, 7,
-72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0, 0, 14, 0, 3,
0, 0, 0, 71, 0, 7, 0, 72, 0, 14, 0, 73, 0, 1, 0, 58,
0, 54, 0, 1, 0, 48, 0, 0, 0, 47, 0, 2, 0, 3, 0, 0,
0, 15, 31, -72, 0, 36, -72, 0, 27, 42, -76, 0, 7, -72, 0, 19,
-79, 0, 0, 0, 1, 0, 49, 0, 0, 0, 14, 0, 3, 0, 0, 0,
76, 0, 7, 0, 77, 0, 14, 0, 78, 0, 1, 0, 58, 0, 55, 0,
1, 0, 48, 0, 0, 0, 47, 0, 1, 0, 2, 0, 0, 0, 15, 35,
-72, 0, 39, -72, 0, 27, 42, -76, 0, 7, -72, 0, 19, -79, 0, 0,
0, 1, 0, 49, 0, 0, 0, 14, 0, 3, 0, 0, 0, 81, 0, 7,
0, 82, 0, 14, 0, 83, 0, 1, 0, 58, 0, 56, 0, 1, 0, 48,
0, 0, 0, 47, 0, 2, 0, 3, 0, 0, 0, 15, 39, -72, 0, 42,
-72, 0, 27, 42, -76, 0, 7, -72, 0, 19, -79, 0, 0, 0, 1, 0,
49, 0, 0, 0, 14, 0, 3, 0, 0, 0, 86, 0, 7, 0, 87, 0,
14, 0, 88, 0, 1, 0, 58, 0, 57, 0, 1, 0, 48, 0, 0, 0,
47, 0, 1, 0, 2, 0, 0, 0, 15, 43, -72, 0, 45, -72, 0, 27,
42, -76, 0, 7, -72, 0, 19, -79, 0, 0, 0, 1, 0, 49, 0, 0,
0, 14, 0, 3, 0, 0, 0, 91, 0, 7, 0, 92, 0, 14, 0, 93,
0, 1, 0, 59, 0, 0, 0, 2, 0, 60,
};
}
public static int copyBuffer(byte[] buf, int address) {
for (int i = 0; i < buf.length; i++) {
Memory.putU1(address + i, buf[i]);
}
return buf.length;
}
public static void main() {
int address = Loader.getBuffer();
int[] buffer_addresses = new int[buffers.length];
for (int i = 0; i < buffers.length; i++) {
buffer_addresses[i] = address;
address += copyBuffer(buffers[i], address);
}
Loader.load(buffer_addresses);
}
}