Skip to content

Commit 895601b

Browse files
committed
VM: update
1 parent 5d5f140 commit 895601b

6 files changed

Lines changed: 121 additions & 37 deletions

File tree

include/openminecraft/vm/pixeltower/om_pixeltower_interpreter.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class OMInterpreter
5757
void operand_istore_n(std::shared_ptr<OMFrameMetadata> frame);
5858
util::OMResult<std::any, err::OMValidationError> operand_invokeinterface(std::shared_ptr<OMFrameMetadata> frame);
5959
util::OMResult<std::any, err::OMValidationError> operand_putstatic(std::shared_ptr<OMFrameMetadata> frame);
60+
util::OMResult<std::any, err::OMValidationError> operand_putfield(std::shared_ptr<OMFrameMetadata> frame);
6061

6162
private:
6263
util::OMResult<std::any, err::OMValidationError> checkType(std::shared_ptr<OMFrameMetadata> frame, std::any data,

include/openminecraft/vm/pixeltower/om_pixeltower_memorymanager.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
namespace openminecraft::vm::pixeltower
1212
{
13+
#define OBJECT_ACCESS(p) ((void *)((uint8_t *)p + sizeof(void *)))
14+
#define ARRAY_ACCESS(p, t) ((t *)((uint8_t *)p + sizeof(openminecraft::vm::pixeltower::OMArrayHeader)))
1315
class OMMemoryManager
1416
{
1517
public:

src/boot/entrypoint.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
#include "openminecraft/vm/classfile/om_class_file.hpp"
3333
#include "openminecraft/vm/err/om_validation_error.hpp"
3434
#include "openminecraft/vm/pixeltower/om_pixeltower.hpp"
35+
#include "openminecraft/vm/pixeltower/om_pixeltower_array_structdef.hpp"
3536
#include "openminecraft/vm/pixeltower/om_pixeltower_interpreter.hpp"
37+
#include "openminecraft/vm/pixeltower/om_pixeltower_memorymanager.hpp"
3638
#include <SDL3/SDL.h>
3739
#include <boost/stacktrace.hpp>
3840
#include <fmt/format.h>
@@ -41,6 +43,7 @@ using namespace openminecraft;
4143
using namespace openminecraft::vm::classfile;
4244
using namespace openminecraft::vm::bytecode;
4345
using namespace openminecraft::binary::hash;
46+
using namespace openminecraft::vm::pixeltower;
4447

4548
#include "openminecraft/resource/bootassets.h"
4649

@@ -111,7 +114,7 @@ int boot(std::vector<std::string> args)
111114

112115
SDL_Quit();
113116

114-
auto pt = std::make_unique<vm::pixeltower::OMPixelTower>();
117+
auto pt = std::make_unique<OMPixelTower>();
115118

116119
std::shared_ptr<OMClassFileParser> parser;
117120
bool recovermode = false;
@@ -158,9 +161,37 @@ int boot(std::vector<std::string> args)
158161
throw l.unwrap_err();
159162
}
160163

161-
std::any_cast<std::shared_ptr<vm::pixeltower::runtime::OMInterpreter>>(pt->interpreter)
164+
auto cls = pt->fetchClass("java/lang/String");
165+
if (cls.type == Err)
166+
{
167+
logger->warn(cls.unwrap_err().what());
168+
break;
169+
}
170+
void *arr = pt->allocateArray(cls.unwrap(), 1);
171+
std::any_cast<std::shared_ptr<runtime::OMInterpreter>>(pt->interpreter)
162172
->stack[std::this_thread::get_id()]
163-
.push(33550336);
173+
.push(arr);
174+
void *rawarr = pt->allocateArray(Byte, 7);
175+
char *arrdata = ((char *)rawarr) + sizeof(OMArrayHeader);
176+
arrdata[0] = '-';
177+
arrdata[1] = '-';
178+
arrdata[2] = 'd';
179+
arrdata[3] = 'e';
180+
arrdata[4] = 'b';
181+
arrdata[5] = 'u';
182+
arrdata[6] = 'g';
183+
void *str = pt->allocate(cls.unwrap());
184+
std::any_cast<std::shared_ptr<runtime::OMInterpreter>>(pt->interpreter)
185+
->stack[std::this_thread::get_id()]
186+
.push(str);
187+
std::any_cast<std::shared_ptr<runtime::OMInterpreter>>(pt->interpreter)
188+
->stack[std::this_thread::get_id()]
189+
.push(rawarr);
190+
auto initresult = std::any_cast<std::shared_ptr<runtime::OMInterpreter>>(pt->interpreter)
191+
->execute(cls.unwrap(), "<init>", "([B)V");
192+
logger->warn(initresult.unwrap_err().what());
193+
194+
ARRAY_ACCESS(rawarr, void *)[0] = str;
164195

165196
auto c = pt->execute("openminecraft/Test", "main", "([Ljava/lang/String;)V");
166197
logger->info(c.unwrap_err().what());

src/vm/bytecode/om_bytecode_descriptor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,17 @@ OMResult<std::string, std::string> decodeType(std::string raw, int *p)
5252
return d;
5353
}
5454
case '[': {
55+
char begin = *p - 1;
5556
while (raw[*p] == '[')
5657
{
5758
*p = *p + 1;
5859
}
60+
char dim = *p - begin;
5961
auto sup = decodeType(raw, p);
6062
switch (sup.type)
6163
{
6264
case Ok:
63-
return OMResult<std::string, std::string>::ok(fmt::format("[{}{}", (char)*p, sup.unwrap()));
65+
return OMResult<std::string, std::string>::ok(fmt::format("[{}{}", dim, sup.unwrap()));
6466
case Err:
6567
return OMResult<std::string, std::string>::err(sup.unwrap_err());
6668
}

src/vm/pixeltower/om_pixeltower_interpreter.cpp

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "openminecraft/vm/pixeltower/om_pixeltower.hpp"
1111
#include "openminecraft/vm/pixeltower/om_pixeltower_array_structdef.hpp"
1212
#include "openminecraft/vm/pixeltower/om_pixeltower_frame_structdef.hpp"
13+
#include "openminecraft/vm/pixeltower/om_pixeltower_memorymanager.hpp"
1314
#include <any>
1415
#include <list>
1516
#include <memory>
@@ -134,7 +135,6 @@ OMResult<std::any, err::OMValidationError> OMInterpreter::execute(std::shared_pt
134135
switch (target.type)
135136
{
136137
case util::Ok: {
137-
logger.debug("typecheck");
138138
break;
139139
}
140140
case util::Err: {
@@ -254,6 +254,11 @@ OMResult<std::any, err::OMValidationError> OMInterpreter::execute(std::shared_pt
254254
break;
255255
}
256256

257+
case op_putfield: {
258+
operand_putfield(frame);
259+
break;
260+
}
261+
257262
case op_invokestatic:
258263
case op_invokespecial:
259264
case op_invokevirtual: {
@@ -380,74 +385,77 @@ OMResult<std::any, err::OMValidationError> OMInterpreter::checkType(std::shared_
380385
fmt::format("array dimension mismatched, required {}, actually {}", (int)desc[1], fetchName(header->type)), \
381386
fetchCurrentPosition(frame)});
382387

383-
switch (desc[2])
388+
auto descp = std::string(desc.c_str()).substr(2);
389+
390+
switch (hash_compile_time(descp.c_str()))
384391
{
385-
case 'B':
392+
case "byte"_hash:
386393
if (header->type != Byte)
387394
{
388395
TYPE_MISMATCH;
389396
}
390397
break;
391-
case 'C':
398+
case "char"_hash:
392399
if (header->type != Char)
393400
{
394401
TYPE_MISMATCH;
395402
}
396403
break;
397-
case 'Z':
404+
case "boolean"_hash:
398405
if (header->type != Boolean)
399406
{
400407
TYPE_MISMATCH;
401408
}
402409
break;
403-
case 'I':
410+
case "int"_hash:
404411
if (header->type != Int)
405412
{
406413
TYPE_MISMATCH;
407414
}
408415
break;
409-
case 'J':
416+
case "long"_hash:
410417
if (header->type != Long)
411418
{
412419
TYPE_MISMATCH;
413420
}
414-
case 'S':
421+
case "short"_hash:
415422
if (header->type != Short)
416423
{
417424
TYPE_MISMATCH;
418425
}
419426
break;
420-
case 'D':
427+
case "double"_hash:
421428
if (header->type != Double)
422429
{
423430
TYPE_MISMATCH;
424431
}
425432
break;
426-
case 'F':
433+
case "float"_hash:
427434
if (header->type != Float)
428435
{
429436
TYPE_MISMATCH;
430437
}
431438
break;
432-
case 'L': {
433-
auto type = tower.fetchClass(std::string(desc.c_str()).substr(3));
434-
if (type.type == util::Err)
435-
{
436-
return OMResult<std::any, err::OMValidationError>::err(type.unwrap_err());
437-
}
438-
if (!tower.classloader->isClassCompat(header->classPointer, type.unwrap()))
439+
default: {
440+
if (descp[0] == 'L')
439441
{
440-
return OMResult<std::any, err::OMValidationError>::err(
441-
{err::Instructions,
442-
fmt::format("class type incomptiable ({} and {})", header->classPointer->name,
443-
type.unwrap()->name),
444-
fetchCurrentPosition(frame)});
442+
auto type = tower.fetchClass(std::string(desc.c_str()).substr(3));
443+
if (type.type == util::Err)
444+
{
445+
return OMResult<std::any, err::OMValidationError>::err(type.unwrap_err());
446+
}
447+
if (!tower.classloader->isClassCompat(header->classPointer, type.unwrap()))
448+
{
449+
return OMResult<std::any, err::OMValidationError>::err(
450+
{err::Instructions,
451+
fmt::format("class type incomptiable ({} and {})", header->classPointer->name,
452+
type.unwrap()->name),
453+
fetchCurrentPosition(frame)});
454+
}
455+
return OMResult<std::any, err::OMValidationError>::ok(nullptr);
445456
}
446-
return OMResult<std::any, err::OMValidationError>::ok(nullptr);
447-
}
448-
default: {
449457
return OMResult<std::any, err::OMValidationError>::err(
450-
{err::Instructions, "unknown descriptor", fetchCurrentPosition(frame)});
458+
{err::Instructions, fmt::format("unknown descriptor {}", desc), fetchCurrentPosition(frame)});
451459
}
452460
}
453461
}
@@ -507,6 +515,7 @@ std::string OMInterpreter::fetchName(OMArrayType type)
507515
return "ref";
508516
}
509517
}
518+
// TODO: other types
510519
void OMInterpreter::writeStackTop(void *target)
511520
{
512521
auto it = std::type_index(STACK_ACCESS.top().type());
@@ -529,6 +538,47 @@ util::OMResult<std::any, err::OMValidationError> OMInterpreter::operand_ireturn(
529538
STACK_ACCESS.push(ret);
530539
return l;
531540
}
541+
OMResult<std::any, err::OMValidationError> OMInterpreter::operand_putfield(std::shared_ptr<OMFrameMetadata> frame)
542+
{
543+
auto mrIdx = binary::be16ToNative(*(uint16_t *)(frame->codePointer + frame->offset + 1));
544+
auto temp1 = frame->clazz->mapping->at(mrIdx)->to<OMClassConstantFieldRef>();
545+
auto temp2 = frame->clazz->mapping->at(temp1->classIndex)->to<OMClassConstantClass>();
546+
auto temp3 = frame->clazz->mapping->at(temp1->nameAndTypeIndex)->to<OMClassConstantNameAndType>();
547+
548+
auto cls = frame->clazz->mapping->at(temp2->nameIndex)->to<OMClassConstantUtf8>()->data;
549+
auto name = frame->clazz->mapping->at(temp3->nameIndex)->to<OMClassConstantUtf8>()->data;
550+
auto desc = frame->clazz->mapping->at(temp3->descIndex)->to<OMClassConstantUtf8>()->data;
551+
552+
auto res = tower.fetchClass(cls);
553+
if (res.type == util::Err)
554+
{
555+
return OMResult<std::any, err::OMValidationError>::err(res.unwrap_err());
556+
}
557+
558+
frame->offset += 3;
559+
auto value = STACK_ACCESS.top();
560+
STACK_ACCESS.pop();
561+
auto item = STACK_ACCESS.top();
562+
STACK_ACCESS.pop();
563+
STACK_ACCESS.push(value);
564+
if (std::type_index(item.type()) != std::type_index(typeid(void *)))
565+
{
566+
return OMResult<std::any, err::OMValidationError>::err(
567+
{err::Instructions, "unknown stack item type", fetchCurrentPosition(frame)});
568+
}
569+
for (auto fi : res.unwrap()->fields)
570+
{
571+
if (fi->name == name && (fi->accessFlag & JVM_Acc_Static) == 0)
572+
{
573+
writeStackTop((uint8_t *)OBJECT_ACCESS(std::any_cast<void *>(item)) + fi->offset);
574+
return OMResult<std::any, err::OMValidationError>::ok(nullptr);
575+
}
576+
}
577+
578+
return OMResult<std::any, err::OMValidationError>::err(
579+
{err::Instructions, fmt::format("static field not found for {} with name {}", cls, name),
580+
fetchCurrentPosition(frame)});
581+
}
532582
OMResult<std::any, err::OMValidationError> OMInterpreter::operand_putstatic(std::shared_ptr<OMFrameMetadata> frame)
533583
{
534584
auto mrIdx = binary::be16ToNative(*(uint16_t *)(frame->codePointer + frame->offset + 1));
@@ -546,17 +596,15 @@ OMResult<std::any, err::OMValidationError> OMInterpreter::operand_putstatic(std:
546596
return OMResult<std::any, err::OMValidationError>::err(res.unwrap_err());
547597
}
548598

599+
frame->offset += 3;
549600
for (auto fi : res.unwrap()->fields)
550601
{
551602
if (fi->name == name && (fi->accessFlag & JVM_Acc_Static))
552603
{
553604
writeStackTop((void *)((uint8_t *)res.unwrap()->staticFieldBlock + fi->offset));
554-
frame->offset += 3;
555605
return OMResult<std::any, err::OMValidationError>::ok(nullptr);
556606
}
557607
}
558-
logger.debug("not found!");
559-
frame->offset += 3;
560608

561609
return OMResult<std::any, err::OMValidationError>::err(
562610
{err::Instructions, fmt::format("static field not found for {} with name {}", cls, name),

src/vm/pixeltower/om_pixeltower_memorymanager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void *OMMemoryManager::allocateArray(std::shared_ptr<OMClass> cls, int *lengths,
4848
arr->type = Reference;
4949
arr->dim = dim;
5050
// offset sizeof(OMArrayHeader) bytes
51-
auto arrdata = (void **)((uint8_t *)result + sizeof(OMArrayHeader));
51+
auto arrdata = ARRAY_ACCESS(result, void *);
5252
for (int i = 0; i < *lengths; i++)
5353
{
5454
arrdata[i] = allocateArray(cls, lengths + 1, dim - 1);
@@ -101,7 +101,7 @@ void *OMMemoryManager::allocateArray(OMArrayType type, int *lengths, int dim)
101101
arr->type = type;
102102
arr->dim = dim;
103103
// offset sizeof(OMArrayHeader) bytes
104-
auto arrdata = (void **)((uint8_t *)result + sizeof(OMArrayHeader));
104+
auto arrdata = ARRAY_ACCESS(result, void *);
105105
for (int i = 0; i < *lengths; i++)
106106
{
107107
arrdata[i] = allocateArray(type, lengths + 1, dim - 1);
@@ -126,7 +126,7 @@ void OMMemoryManager::searchFromInstance(void *b)
126126
{
127127
return;
128128
}
129-
auto arr = (void **)((uint8_t *)b + sizeof(OMArrayHeader));
129+
auto arr = ARRAY_ACCESS(b, void *);
130130
for (int i = 0; i < arrh->length; i++)
131131
{
132132
searchFromInstance(arr[i]);
@@ -135,7 +135,7 @@ void OMMemoryManager::searchFromInstance(void *b)
135135
else
136136
{
137137
auto clazz = *((OMClass **)b);
138-
auto arrdata = ((uint8_t *)b + sizeof(void *));
138+
auto arrdata = (uint8_t *)OBJECT_ACCESS(b);
139139
for (auto fi : clazz->fields)
140140
{
141141
if (fi->type == OMFieldType::BytesP && (fi->accessFlag & JVM_Acc_Static) == 0)

0 commit comments

Comments
 (0)