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
510519void 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+ }
532582OMResult<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),
0 commit comments