@@ -147,7 +147,7 @@ static const char *in_packet_string()
147
147
{
148
148
int length ;
149
149
const char * string = in_packet_bytes (& length );
150
- if (string [length ] != 0 ) {
150
+ if (string [length - 1 ] != 0 ) {
151
151
log ("session.c: string is not zero-terminated" );
152
152
return "" ;
153
153
}
@@ -346,6 +346,8 @@ enum {
346
346
REMOTEMSG_TYPE_FLASH_ERROR_REPLY
347
347
};
348
348
349
+ static int receive_rpc_value (const char * * tag , void * * slot );
350
+
349
351
static int process_input (void )
350
352
{
351
353
switch (buffer_in .header .type ) {
@@ -457,23 +459,37 @@ static int process_input(void)
457
459
user_kernel_state = USER_KERNEL_RUNNING ;
458
460
break ;
459
461
460
- // case REMOTEMSG_TYPE_RPC_REPLY: {
461
- // struct msg_rpc_reply reply;
462
+ case REMOTEMSG_TYPE_RPC_REPLY : {
463
+ struct msg_rpc_recv_request * request ;
464
+ struct msg_rpc_recv_reply reply ;
462
465
463
- // int result = in_packet_int32();
466
+ if (user_kernel_state != USER_KERNEL_WAIT_RPC ) {
467
+ log ("Unsolicited RPC reply" );
468
+ return 0 ; // restart session
469
+ }
470
+
471
+ request = mailbox_wait_and_receive ();
472
+ if (request -> type != MESSAGE_TYPE_RPC_RECV_REQUEST ) {
473
+ log ("Expected MESSAGE_TYPE_RPC_RECV_REQUEST, got %d" ,
474
+ request -> type );
475
+ return 0 ; // restart session
476
+ }
464
477
465
- // if(user_kernel_state != USER_KERNEL_WAIT_RPC) {
466
- // log("Unsolicited RPC reply");
467
- // return 0; // restart session
468
- // }
478
+ const char * tag = in_packet_string ();
479
+ void * slot = request -> slot ;
480
+ if (!receive_rpc_value (& tag , & slot )) {
481
+ log ("Failed to receive RPC reply" );
482
+ return 0 ; // restart session
483
+ }
469
484
470
- // reply.type = MESSAGE_TYPE_RPC_REPLY;
471
- // reply.result = result;
472
- // mailbox_send_and_wait(&reply);
485
+ reply .type = MESSAGE_TYPE_RPC_RECV_REPLY ;
486
+ reply .alloc_size = 0 ;
487
+ reply .exception = NULL ;
488
+ mailbox_send_and_wait (& reply );
473
489
474
- // user_kernel_state = USER_KERNEL_RUNNING;
475
- // break;
476
- // }
490
+ user_kernel_state = USER_KERNEL_RUNNING ;
491
+ break ;
492
+ }
477
493
478
494
case REMOTEMSG_TYPE_RPC_EXCEPTION : {
479
495
struct msg_rpc_recv_request * request ;
@@ -512,13 +528,191 @@ static int process_input(void)
512
528
}
513
529
514
530
default :
531
+ log ("Received invalid packet type %d from host" ,
532
+ buffer_in .header .type );
533
+ return 0 ;
534
+ }
535
+
536
+ return 1 ;
537
+ }
538
+
539
+ // See comm_generic.py:_{send,receive}_rpc_value and llvm_ir_generator.py:_rpc_tag.
540
+ static void skip_rpc_value (const char * * tag ) {
541
+ switch (* (* tag )++ ) {
542
+ case 't' : {
543
+ int size = * (* tag )++ ;
544
+ for (int i = 0 ; i < size ; i ++ )
545
+ skip_rpc_value (tag );
546
+ break ;
547
+ }
548
+
549
+ case 'l' :
550
+ skip_rpc_value (tag );
551
+ break ;
552
+
553
+ case 'r' :
554
+ skip_rpc_value (tag );
555
+ break ;
556
+ }
557
+ }
558
+
559
+ static int sizeof_rpc_value (const char * * tag )
560
+ {
561
+ switch (* (* tag )++ ) {
562
+ case 't' : { // tuple
563
+ int size = * (* tag )++ ;
564
+
565
+ int32_t length = 0 ;
566
+ for (int i = 0 ; i < size ; i ++ )
567
+ length += sizeof_rpc_value (tag );
568
+ return length ;
569
+ }
570
+
571
+ case 'n' : // None
572
+ return 0 ;
573
+
574
+ case 'b' : // bool
575
+ return sizeof (int8_t );
576
+
577
+ case 'i' : // int(width=32)
578
+ return sizeof (int32_t );
579
+
580
+ case 'I' : // int(width=64)
581
+ return sizeof (int64_t );
582
+
583
+ case 'f' : // float
584
+ return sizeof (double );
585
+
586
+ case 'F' : // Fraction
587
+ return sizeof (struct { int64_t numerator , denominator ; });
588
+
589
+ case 's' : // string
590
+ return sizeof (char * );
591
+
592
+ case 'l' : // list(elt='a)
593
+ skip_rpc_value (tag );
594
+ return sizeof (struct { int32_t length ; struct {} * elements ; });
595
+
596
+ case 'r' : // range(elt='a)
597
+ return sizeof_rpc_value (tag ) * 3 ;
598
+
599
+ default :
600
+ log ("sizeof_rpc_value: unknown tag %02x" , * ((* tag ) - 1 ));
601
+ return 0 ;
602
+ }
603
+ }
604
+
605
+ static void * alloc_rpc_value (int size )
606
+ {
607
+ struct msg_rpc_recv_request * request ;
608
+ struct msg_rpc_recv_reply reply ;
609
+
610
+ reply .type = MESSAGE_TYPE_RPC_RECV_REPLY ;
611
+ reply .alloc_size = size ;
612
+ reply .exception = NULL ;
613
+ mailbox_send_and_wait (& reply );
614
+
615
+ request = mailbox_wait_and_receive ();
616
+ if (request -> type != MESSAGE_TYPE_RPC_RECV_REQUEST ) {
617
+ log ("Expected MESSAGE_TYPE_RPC_RECV_REQUEST, got %d" ,
618
+ request -> type );
619
+ return NULL ;
620
+ }
621
+ return request -> slot ;
622
+ }
623
+
624
+ static int receive_rpc_value (const char * * tag , void * * slot )
625
+ {
626
+ switch (* (* tag )++ ) {
627
+ case 't' : { // tuple
628
+ int size = * (* tag )++ ;
629
+
630
+ for (int i = 0 ; i < size ; i ++ ) {
631
+ if (!receive_rpc_value (tag , slot ))
632
+ return 0 ;
633
+ }
634
+ break ;
635
+ }
636
+
637
+ case 'n' : // None
638
+ break ;
639
+
640
+ case 'b' : { // bool
641
+ * ((* (int8_t * * )slot )++ ) = in_packet_int8 ();
642
+ break ;
643
+ }
644
+
645
+ case 'i' : { // int(width=32)
646
+ * ((* (int32_t * * )slot )++ ) = in_packet_int32 ();
647
+ break ;
648
+ }
649
+
650
+ case 'I' : { // int(width=64)
651
+ * ((* (int64_t * * )slot )++ ) = in_packet_int64 ();
652
+ break ;
653
+ }
654
+
655
+ case 'f' : { // float
656
+ * ((* (int64_t * * )slot )++ ) = in_packet_int64 ();
657
+ break ;
658
+ }
659
+
660
+ case 'F' : { // Fraction
661
+ struct { int64_t numerator , denominator ; } * fraction = * slot ;
662
+ fraction -> numerator = in_packet_int64 ();
663
+ fraction -> denominator = in_packet_int64 ();
664
+ * slot = (void * )((intptr_t )(* slot ) + sizeof (* fraction ));
665
+ break ;
666
+ }
667
+
668
+ case 's' : { // string
669
+ const char * in_string = in_packet_string ();
670
+ char * out_string = alloc_rpc_value (strlen (in_string ) + 1 );
671
+ memcpy (out_string , in_string , strlen (in_string ) + 1 );
672
+ * ((* (char * * * )slot )++ ) = out_string ;
673
+ break ;
674
+ }
675
+
676
+ case 'l' : { // list(elt='a)
677
+ struct { int32_t length ; struct {} * elements ; } * list = * slot ;
678
+ list -> length = in_packet_int32 ();
679
+
680
+ const char * tag_copy = * tag ;
681
+ list -> elements = alloc_rpc_value (sizeof_rpc_value (& tag_copy ) * list -> length );
682
+
683
+ void * element = list -> elements ;
684
+ for (int i = 0 ; i < list -> length ; i ++ ) {
685
+ const char * tag_copy = * tag ;
686
+ if (!receive_rpc_value (& tag_copy , & element ))
687
+ return 0 ;
688
+ }
689
+ skip_rpc_value (tag );
690
+ break ;
691
+ }
692
+
693
+ case 'r' : { // range(elt='a)
694
+ const char * tag_copy ;
695
+ tag_copy = * tag ;
696
+ if (!receive_rpc_value (& tag_copy , slot )) // min
697
+ return 0 ;
698
+ tag_copy = * tag ;
699
+ if (!receive_rpc_value (& tag_copy , slot )) // max
700
+ return 0 ;
701
+ tag_copy = * tag ;
702
+ if (!receive_rpc_value (& tag_copy , slot )) // step
703
+ return 0 ;
704
+ * tag = tag_copy ;
705
+ break ;
706
+ }
707
+
708
+ default :
709
+ log ("receive_rpc_value: unknown tag %02x" , * ((* tag ) - 1 ));
515
710
return 0 ;
516
711
}
517
712
518
713
return 1 ;
519
714
}
520
715
521
- // See llvm_ir_generator.py:_rpc_tag.
522
716
static int send_rpc_value (const char * * tag , void * * value )
523
717
{
524
718
if (!out_packet_int8 (* * tag ))
@@ -541,51 +735,33 @@ static int send_rpc_value(const char **tag, void **value)
541
735
break ;
542
736
543
737
case 'b' : { // bool
544
- int size = sizeof (int8_t );
545
- if (!out_packet_chunk (* value , size ))
546
- return 0 ;
547
- * value = (void * )((intptr_t )(* value ) + size );
548
- break ;
738
+ return out_packet_int8 (* ((* (int8_t * * )value )++ ));
549
739
}
550
740
551
741
case 'i' : { // int(width=32)
552
- int size = sizeof (int32_t );
553
- if (!out_packet_chunk (* value , size ))
554
- return 0 ;
555
- * value = (void * )((intptr_t )(* value ) + size );
556
- break ;
742
+ return out_packet_int32 (* ((* (int32_t * * )value )++ ));
557
743
}
558
744
559
745
case 'I' : { // int(width=64)
560
- int size = sizeof (int64_t );
561
- if (!out_packet_chunk (* value , size ))
562
- return 0 ;
563
- * value = (void * )((intptr_t )(* value ) + size );
564
- break ;
746
+ return out_packet_int64 (* ((* (int64_t * * )value )++ ));
565
747
}
566
748
567
749
case 'f' : { // float
568
- int size = sizeof (double );
569
- if (!out_packet_chunk (* value , size ))
570
- return 0 ;
571
- * value = (void * )((intptr_t )(* value ) + size );
572
- break ;
750
+ return out_packet_float64 (* ((* (double * * )value )++ ));
573
751
}
574
752
575
753
case 'F' : { // Fraction
576
- int size = sizeof (int64_t ) * 2 ;
577
- if (!out_packet_chunk (* value , size ))
754
+ struct { int64_t numerator , denominator ; } * fraction = * value ;
755
+ if (!out_packet_int64 (fraction -> numerator ))
756
+ return 0 ;
757
+ if (!out_packet_int64 (fraction -> denominator ))
578
758
return 0 ;
579
- * value = (void * )((intptr_t )(* value ) + size );
759
+ * value = (void * )((intptr_t )(* value ) + sizeof ( * fraction ) );
580
760
break ;
581
761
}
582
762
583
763
case 's' : { // string
584
- const char * * string = * value ;
585
- if (!out_packet_string (* string ))
586
- return 0 ;
587
- * value = (void * )((intptr_t )(* value ) + strlen (* string ) + 1 );
588
- break ;
764
+ return out_packet_string (* ((* (const char * * * )value )++ ));
589
765
}
590
766
591
767
case 'l' : { // list(elt='a)
@@ -595,11 +771,11 @@ static int send_rpc_value(const char **tag, void **value)
595
771
if (!out_packet_int32 (list -> length ))
596
772
return 0 ;
597
773
598
- const char * tag_copy ;
774
+ const char * tag_copy = * tag ;
599
775
for (int i = 0 ; i < list -> length ; i ++ ) {
600
- tag_copy = * tag ;
601
776
if (!send_rpc_value (& tag_copy , & element ))
602
777
return 0 ;
778
+ tag_copy = * tag ;
603
779
}
604
780
* tag = tag_copy ;
605
781
@@ -634,7 +810,7 @@ static int send_rpc_value(const char **tag, void **value)
634
810
if (option -> present ) {
635
811
return send_rpc_value (tag , & contents );
636
812
} else {
637
- ( * tag )++ ;
813
+ skip_rpc_value ( tag );
638
814
break ;
639
815
}
640
816
}
@@ -668,8 +844,7 @@ static int send_rpc_request(int service, const char *tag, va_list args)
668
844
}
669
845
out_packet_int8 (0 );
670
846
671
- out_packet_string (tag + 1 );
672
-
847
+ out_packet_string (tag + 1 ); // return tags
673
848
out_packet_finish ();
674
849
return 1 ;
675
850
}
0 commit comments