History

Altered API getting the allocation from a vm_alloc_t. Added preliminary internal file descriptor type. Test groups now print out their name.

arr committed 10 years ago

Commit 5a417ba1 parent 9881f459 files · +230 −104Browse files

Unified · Split

9 files
  1. limbo/basic_limbo_tests.b +80 −62
  2. src/include/runtime.h +7 −1
  3. src/vm/execution_table.cpp +23 −23
  4. src/vm/garbage_collector.cpp +1 −1
  5. src/vm/module_reader.cpp +3 −3
  6. src/vm/sys/Sysmod.cpp +105 −3
  7. src/vm/sys/print.cpp +1 −1
  8. src/vm/thread.cpp +5 −5
  9. src/vm/vm_memory.cpp +5 −5
limbo/basic_limbo_tests.b+80−62
@@ -8,27 +8,30 @@ Hello: module · 7 unmodified lines
88 init: fn();
99 };
1010
11+sys : Sys;
12+
1113 init()
1214 {
1315 a := "foobar!";
14− sys := load Sys Sys->PATH;
15− sys->print("Hello, %s %o %d %x\n%s%%%% %H", "world!", 8, 10, 16, "------------------\n", a);
16−
17− #test_function_refs();
18− #test_alt();
19− #test_channel();
20− #test_spawn();
21− #test_exceptions();
22− #test_case();
23− #test_discriminated_union();
24− #test_external_module();
25− #test_fixed_point();
26− #test_exponent();
27− #test_string();
28− #test_array();
29− #test_list();
30− #test_branch();
31− #test_for_loop_function_call();
16+ sys = load Sys Sys->PATH;
17+ big_val := big 16r12345;
18+ sys->print("Hello, %s %o %d %x %bd %f\n%s%%%% %H\n\n", "world!", 8, 10, 16, big_val, 0.1, "------------------\n", a);
19+
20+ test_function_refs();
21+ test_alt();
22+ test_channel();
23+ test_spawn();
24+ test_exceptions();
25+ test_case();
26+ test_discriminated_union();
27+ test_external_module();
28+ test_fixed_point();
29+ test_exponent();
30+ test_string();
31+ test_array();
32+ test_list();
33+ test_branch();
34+ test_for_loop_function_call();
3235 }
3336
3437 str_cmp(s1: string, s2: string): int
@@ -43,6 +46,7 @@ str_cmp(s1: string, s2: string): int · 8 unmodified lines
4346
4447 test_function_refs()
4548 {
49+ sys->print("test_function_refs()\n");
4650 f : ref fn(s1: string, s2: string): int;
4751 f = str_cmp;
4852
@@ -54,6 +58,7 @@ test_function_refs() · 5 unmodified lines
5458
5559 test_alt()
5660 {
61+ sys->print("test_alt()\n");
5762 int_chan_10 := chan of int;
5863 int_chan_20 := chan of int;
5964 int_chan_done := chan of int;
@@ -144,6 +149,7 @@ alt2(ten : chan of int, twenty : chan of int, done : chan of int) · 84 unmodified lines
144149
145150 test_channel()
146151 {
152+ sys->print("test_channel()\n");
147153 test_channel_int(nil);
148154 test_channel_int_buffered(nil, nil);
149155
@@ -327,6 +333,7 @@ test_channel_ref_adt_buffered(c : chan of ref ChannelAdt, r : chan of ref Channe · 177 unmodified lines
327333
328334 test_spawn()
329335 {
336+ sys->print("test_spawn()\n");
330337 spawn th1();
331338 }
332339
@@ -342,23 +349,24 @@ TESTEXCEPTION : exception(int, int); · 9 unmodified lines
342349
343350 test_exceptions()
344351 {
352+ sys->print("test_exceptions()\n");
345353 {
346354 raise TESTEXCEPTION(5,10);
347355 } exception e {
348− TESTEXCEPTION =>
356+ TESTEXCEPTION =>
349357 (a,b) := e;
350358 if (a != 5 || b != 10) exit;
351359
352360 * => exit;
353361 }
354−
362+
355363 {
356364 raise "bad time";
357365 } exception e {
358366 "bad time" => ;
359367 * => exit;
360368 }
361−
369+
362370 s := 0;
363371 {
364372 raise_exception_1(0);
@@ -421,6 +429,7 @@ raise_exception_n(d : int, s:string) · 56 unmodified lines
421429
422430 test_case()
423431 {
432+ sys->print("test_case()\n");
424433 {
425434 s := 0;
426435 v := 150;
@@ -431,7 +440,7 @@ test_case() · 4 unmodified lines
431440 201 to 300 => s = 0;
432441 * => s = 0;
433442 }
434−
443+
435444 if (s != 1) exit;
436445 }
437446
@@ -444,7 +453,7 @@ test_case() · 6 unmodified lines
444453 "FOO" or "foo" => s = 1;
445454 * => s = 0;
446455 }
447−
456+
448457 if (s != 1) exit;
449458 }
450459
@@ -458,7 +467,7 @@ test_case() · 7 unmodified lines
458467 16r400000000 => s = 0;
459468 * => s = 0;
460469 }
461−
470+
462471 if (s != 1) exit;
463472 }
464473 }
@@ -477,6 +486,7 @@ Constant: adt · 12 unmodified lines
477486
478487 test_discriminated_union()
479488 {
489+ sys->print("test_discriminated_union()\n");
480490 c : ref Constant = ref Constant.Real("pi", 3.14);
481491 pick x := c
482492 {
@@ -491,18 +501,19 @@ test_discriminated_union() · 8 unmodified lines
491501
492502 test_external_module()
493503 {
504+ sys->print("test_external_module()\n");
494505 ext_mod := load ExtModule ExtModule->PATH;
495506
496507 {
497508 module_int := ext_mod->return_int();
498509 if (module_int != ext_mod->module_constant) exit;
499510 }
500−
511+
501512 {
502513 thirty_four := ext_mod->double_int(17);
503514 if (thirty_four != 34) exit;
504515 }
505−
516+
506517 {
507518 d := ext_mod->return_datatype();
508519 dr := ext_mod->return_datatype_ref();
@@ -515,6 +526,7 @@ test_external_module() · 6 unmodified lines
515526
516527 test_fixed_point()
517528 {
529+ sys->print("test_fixed_point()\n");
518530 fpt : type fixed(0.125, 512.0);
519531 a := fpt(1.1);
520532 b := fpt(2.1);
@@ -524,6 +536,7 @@ test_fixed_point() · 3 unmodified lines
524536
525537 test_exponent()
526538 {
539+ sys->print("test_exponent()\n");
527540 {
528541 base := 2;
529542 power := 3;
@@ -587,27 +600,28 @@ test_exponent() · 57 unmodified lines
587600
588601 test_string()
589602 {
603+ sys->print("test_string()\n");
590604 count4 := "abcd";
591605 if (len count4 != 4) exit;
592606
593607 array4 := array of byte count4;
594608 if (len array4 != 4) exit;
595−
609+
596610 count6 := "わがよたれぞ";
597611 if (len count6 != 6) exit;
598−
612+
599613 array18 := array of byte count6;
600614 if (len array18 != 18) exit;
601615
602616 count6_2 := string array18;
603617 if (count6 != count6_2) exit;
604−
618+
605619 count7 := "खा सकता";
606620 if (len count7 != 7) exit;
607−
621+
608622 array19 := array of byte count7;
609623 if (len array19 != 19) exit;
610−
624+
611625 count36 := "abcdefghijklmnopqrstuvwxyz0123456789";
612626 if (len count36 != 36) exit;
613627
@@ -622,7 +636,7 @@ test_string() · 8 unmodified lines
622636 str[len str] = ch + 4;
623637 if (len str != 5) exit;
624638 if (str[2] != 'c') exit;
625−
639+
626640 str[2] = 'よ';
627641 if (len str != 5) exit;
628642 if (str[2] != 'よ') exit;
@@ -633,14 +647,14 @@ test_string() · 4 unmodified lines
633647 str_l := "a";
634648 str_l2 := "a";
635649 str_g := "z";
636−
650+
637651 if (!(str_l == str_l)) exit;
638652 if (!(str_l == str_l2)) exit;
639653 if (!(str_l <= str_l2)) exit;
640654 if (!(str_l >= str_l2)) exit;
641655 if (!(str_l < str_g)) exit;
642656 if (!(str_g > str_l)) exit;
643−
657+
644658 str_e : string;
645659 if (str_l == str_e) exit;
646660 if (!(str_l != str_e)) exit;
@@ -648,7 +662,7 @@ test_string() · 1 unmodified line
648662 if (!(str_l >= str_e)) exit;
649663 if (str_l < str_e) exit;
650664 if (!(str_g > str_e)) exit;
651−
665+
652666 if (str_e == str_l) exit;
653667 if (!(str_e != str_l)) exit;
654668 if (!(str_e <= str_l)) exit;
@@ -658,18 +672,18 @@ test_string() · 3 unmodified lines
658672 }
659673
660674 # Compare (multi-byte)
661− {
675+ {
662676 str_l := "Α";
663677 str_l2 := "Α";
664678 str_g := "Ω";
665−
679+
666680 if (!(str_l == str_l)) exit;
667681 if (!(str_l == str_l2)) exit;
668682 if (!(str_l <= str_l2)) exit;
669683 if (!(str_l >= str_l2)) exit;
670684 if (!(str_l < str_g)) exit;
671685 if (!(str_g > str_l)) exit;
672−
686+
673687 str_e : string;
674688 if (str_l == str_e) exit;
675689 if (!(str_l != str_e)) exit;
@@ -677,7 +691,7 @@ test_string() · 1 unmodified line
677691 if (!(str_l >= str_e)) exit;
678692 if (str_l < str_e) exit;
679693 if (!(str_g > str_e)) exit;
680−
694+
681695 if (str_e == str_l) exit;
682696 if (!(str_e != str_l)) exit;
683697 if (!(str_e <= str_l)) exit;
@@ -687,18 +701,18 @@ test_string() · 3 unmodified lines
687701 }
688702
689703 # Compare (multi-byte/ascii mix)
690− {
704+ {
691705 str_l := "a";
692706 str_l2 := "a";
693707 str_g := "Ω";
694−
708+
695709 if (!(str_l == str_l)) exit;
696710 if (!(str_l == str_l2)) exit;
697711 if (!(str_l <= str_l2)) exit;
698712 if (!(str_l >= str_l2)) exit;
699713 if (!(str_l < str_g)) exit;
700714 if (!(str_g > str_l)) exit;
701−
715+
702716 str_e : string;
703717 if (str_l == str_e) exit;
704718 if (!(str_l != str_e)) exit;
@@ -706,7 +720,7 @@ test_string() · 1 unmodified line
706720 if (!(str_l >= str_e)) exit;
707721 if (str_l < str_e) exit;
708722 if (!(str_g > str_e)) exit;
709−
723+
710724 if (str_e == str_l) exit;
711725 if (!(str_e != str_l)) exit;
712726 if (!(str_e <= str_l)) exit;
@@ -720,17 +734,17 @@ test_string() · 7 unmodified lines
720734 s1 := "1";
721735 s2 := "2";
722736 s3 : string;
723−
737+
724738 s4 := s1 + s2;
725739 if (s4 != "12") exit;
726−
740+
727741 s1 += s2;
728742 if (s1 != "12") exit;
729−
743+
730744 s5 := s3 + s1;
731745 s6 := s3 + s3;
732746 }
733−
747+
734748 # Slice
735749 {
736750 s1 := "01234567";
@@ -747,7 +761,7 @@ test_string() · 10 unmodified lines
747761 w_val := 12345;
748762 s_w := string w_val;
749763 if (s_w != "12345") exit;
750−
764+
751765 r_val := 3.14;
752766 s_r := string r_val;
753767 if (s_r != "3.14") exit;
@@ -762,7 +776,7 @@ test_string() · 8 unmodified lines
762776 s_w := "12345";
763777 w_val := int s_w;
764778 if (w_val != 12345) exit;
765−
779+
766780 s_r := "3.14";
767781 r_val := real s_r;
768782 if (r_val != 3.14) exit;
@@ -775,10 +789,11 @@ test_string() · 6 unmodified lines
775789
776790 test_array()
777791 {
792+ sys->print("test_array()\n");
778793 arr : array of int;
779794 a := len arr;
780795 if (a != 0) exit;
781−
796+
782797 test_array_byte();
783798 test_array_int();
784799 test_array_big();
@@ -875,6 +890,7 @@ test_array_real() · 90 unmodified lines
875890
876891 test_list()
877892 {
893+ sys->print("test_list()\n");
878894 lst : list of int;
879895 l := len lst;
880896 if (l != 0) exit;
@@ -892,7 +908,7 @@ test_list_byte() · 11 unmodified lines
892908 lst1 := byte 16rff :: lst0;
893909 lst2 := byte 16rfe :: lst1;
894910 lst3 := byte 16rfd :: lst2;
895−
911+
896912 if (len lst3 != 3) exit;
897913 if (hd lst3 != byte 16rfd) exit;
898914 if (hd tl tl lst3 != byte 16rff) exit;
@@ -904,7 +920,7 @@ test_list_int() · 5 unmodified lines
904920 lst1 := 16rff00 :: lst0;
905921 lst2 := 16rfe00 :: lst1;
906922 lst3 := 16rfd00 :: lst2;
907−
923+
908924 if (len lst3 != 3) exit;
909925 if (hd lst3 != 16rfd00) exit;
910926 if (hd tl tl lst3 != 16rff00) exit;
@@ -916,7 +932,7 @@ test_list_big() · 5 unmodified lines
916932 lst1 := 16rff000000ff000000 :: lst0;
917933 lst2 := 16rfe000000ff000000 :: lst1;
918934 lst3 := 16rfd000000ff000000 :: lst2;
919−
935+
920936 if (len lst3 != 3) exit;
921937 if (hd lst3 != 16rfd000000ff000000) exit;
922938 if (hd tl tl lst3 != 16rff000000ff000000) exit;
@@ -928,7 +944,7 @@ test_list_real() · 5 unmodified lines
928944 lst1 := 3.0 :: lst0;
929945 lst2 := 2.0 :: lst1;
930946 lst3 := 1.0 :: lst2;
931−
947+
932948 if (len lst3 != 3) exit;
933949 if (hd lst3 != 1.0) exit;
934950 if (hd tl tl lst3 != 3.0) exit;
@@ -947,7 +963,7 @@ test_list_adt() · 12 unmodified lines
947963 lst1 := ( "three", 3.0 ) :: lst0;
948964 lst2 := ( "two", 2.0 ) :: lst1;
949965 lst3 := ( "one", 1.0 ) :: lst2;
950−
966+
951967 if (len lst3 != 3) exit;
952968 if ((hd lst3).r != 1.0) exit;
953969 if ((hd tl tl lst3).r != 3.0) exit;
@@ -961,7 +977,7 @@ test_list_adt() · 7 unmodified lines
961977 lst1 := e3 :: lst0;
962978 lst2 := e2 :: lst1;
963979 lst3 := e1 :: lst2;
964−
980+
965981 if (len lst3 != 3) exit;
966982 if ((hd lst3).r != 1.0) exit;
967983 if ((hd tl tl lst3).r != 3.0) exit;
@@ -970,12 +986,13 @@ test_list_adt() · 2 unmodified lines
970986
971987 test_branch()
972988 {
989+ sys->print("test_branch()\n");
973990 test_branch_byte();
974991 test_branch_int();
975992 test_branch_big();
976993 test_branch_real();
977994 }
978−
995+
979996 test_branch_byte()
980997 {
981998 a := byte 16rff;
@@ -985,7 +1002,7 @@ test_branch_byte() · 3 unmodified lines
9851002 if (a != b) exit;
9861003 if (!(a == b)) exit;
9871004 }
988−
1005+
9891006 test_branch_int()
9901007 {
9911008 a := 1024;
@@ -995,7 +1012,7 @@ test_branch_int() · 3 unmodified lines
9951012 if (a != b) exit;
9961013 if (!(a == b)) exit;
9971014 }
998−
1015+
9991016 test_branch_big()
10001017 {
10011018 a := 16r10000000FFFFFFFF;
@@ -1018,11 +1035,12 @@ test_branch_real() · 16 unmodified lines
10181035
10191036 test_for_loop_function_call()
10201037 {
1021− for (j := 0; j < 20; j++)
1038+ sys->print("test_for_loop_function_call()\n");
1039+ for (j := 0; j < 20; j++)
10221040 {
10231041 is_odd := odd(j);
10241042 is_even := even(j);
1025−
1043+
10261044 if (j % 2 == 0)
10271045 {
10281046 if (is_odd != 0) exit;
@@ -1050,4 +1068,4 @@ even(a: int) : int · 21 unmodified lines
10501068 return 1;
10511069
10521070 return odd(a - 1);
1053−}
1071+}
src/include/runtime.h+7−1
@@ -134,7 +134,13 @@ namespace disvm · 133 unmodified lines
134134 pointer_t gc_reserved;
135135
136136 public:
137− pointer_t allocation() const;
137+ pointer_t get_allocation() const;
138+
139+ template <typename T>
140+ T *get_allocation() const
141+ {
142+ return reinterpret_cast<T *>(get_allocation());
143+ }
138144
139145 private:
140146 std::atomic<std::size_t> _ref_count;
src/vm/execution_table.cpp+23−23
@@ -152,7 +152,7 @@ namespace · 151 unmodified lines
152152
153153 auto str = at_val<vm_string_t>(r.src);
154154 auto new_array = new vm_array_t(str);
155− pt_ref(r.dest) = new_array->allocation();
155+ pt_ref(r.dest) = new_array->get_allocation();
156156 }
157157
158158 EXEC_DECL(cvtac)
@@ -167,7 +167,7 @@ namespace · 8 unmodified lines
167167 throw vm_user_exception{ "Invalid array element type for string conversion" };
168168
169169 auto new_string = new vm_string_t(arr->get_length(), reinterpret_cast<uint8_t *>(arr->at(0)));
170− str = new_string->allocation();
170+ str = new_string->get_allocation();
171171 }
172172
173173 pt_ref(r.dest) = str;
@@ -196,7 +196,7 @@ namespace · 22 unmodified lines
196196 auto str = at_val<vm_string_t>(r.dest);
197197 dec_ref_count_and_free(str);
198198
199− pt_ref(r.dest) = new_string->allocation();
199+ pt_ref(r.dest) = new_string->get_allocation();
200200 }
201201
202202 EXEC_DECL(cvtcf)
@@ -221,7 +221,7 @@ namespace · 18 unmodified lines
221221 auto new_string = new vm_string_t(len, reinterpret_cast<uint8_t *>(buffer.data()));
222222
223223 auto str = at_val<vm_string_t>(r.dest);
224− pt_ref(r.dest) = new_string->allocation();
224+ pt_ref(r.dest) = new_string->get_allocation();
225225 dec_ref_count_and_free(str);
226226 }
227227
@@ -247,7 +247,7 @@ namespace · 19 unmodified lines
247247 auto new_string = new vm_string_t(len, reinterpret_cast<uint8_t *>(buffer.data()));
248248
249249 auto str = at_val<vm_string_t>(r.dest);
250− pt_ref(r.dest) = new_string->allocation();
250+ pt_ref(r.dest) = new_string->get_allocation();
251251 dec_ref_count_and_free(str);
252252 }
253253
@@ -399,7 +399,7 @@ namespace · 145 unmodified lines
399399 if (alloc != nullptr)
400400 {
401401 alloc->add_ref();
402− pt_ref(dest) = alloc->allocation();
402+ pt_ref(dest) = alloc->get_allocation();
403403 }
404404 else
405405 {
@@ -626,7 +626,7 @@ namespace · 220 unmodified lines
626626 auto old_str = at_val<vm_string_t>(r.dest);
627627 if (str != old_str)
628628 {
629− pt_ref(r.dest) = str->allocation();
629+ pt_ref(r.dest) = str->get_allocation();
630630 dec_ref_count_and_free(old_str);
631631 }
632632 }
@@ -678,7 +678,7 @@ namespace · 45 unmodified lines
678678
679679 if (!append_to_source)
680680 {
681− pt_ref(r.dest) = str->allocation();
681+ pt_ref(r.dest) = str->get_allocation();
682682 dec_ref_count_and_free(dest_maybe);
683683 }
684684 }
@@ -692,7 +692,7 @@ namespace · 7 unmodified lines
692692 if (str != nullptr)
693693 {
694694 auto new_string = new vm_string_t(*str, start, end);
695− pt_ref(r.dest) = new_string->allocation();
695+ pt_ref(r.dest) = new_string->get_allocation();
696696 }
697697 else if (start == 0 && end == 0)
698698 {
@@ -744,7 +744,7 @@ namespace · 45 unmodified lines
744744 if (arr->alloc_type->map_in_bytes > 0)
745745 vm.get_garbage_collector().track_allocation(new_array);
746746
747− pt_ref(r.dest) = new_array->allocation();
747+ pt_ref(r.dest) = new_array->get_allocation();
748748 }
749749
750750 EXEC_DECL(slicela)
@@ -810,7 +810,7 @@ namespace · 59 unmodified lines
810810 auto value = vt_ref<PrimitiveType>(r.src);
811811 vt_ref<PrimitiveType>(new_list->value()) = value;
812812
813− pt_ref(r.dest) = new_list->allocation();
813+ pt_ref(r.dest) = new_list->get_allocation();
814814 }
815815
816816 EXEC_DECL(consb) { _cons<byte_t>(r); }
@@ -830,7 +830,7 @@ namespace · 13 unmodified lines
830830 if (alloc != nullptr)
831831 {
832832 alloc->add_ref();
833− pt_ref(new_list->value()) = alloc->allocation();
833+ pt_ref(new_list->value()) = alloc->get_allocation();
834834
835835 vm.get_garbage_collector().track_allocation(new_list);
836836 }
@@ -840,7 +840,7 @@ namespace · 3 unmodified lines
840840 }
841841
842842 // Return the list
843− pt_ref(r.dest) = new_list->allocation();
843+ pt_ref(r.dest) = new_list->get_allocation();
844844 }
845845
846846 EXEC_DECL(consmp)
@@ -866,7 +866,7 @@ namespace · 19 unmodified lines
866866 vm.get_garbage_collector().track_allocation(new_list);
867867
868868 // Return the list
869− pt_ref(r.dest) = new_list->allocation();
869+ pt_ref(r.dest) = new_list->get_allocation();
870870 }
871871
872872 template<typename PrimitiveType>
@@ -917,7 +917,7 @@ namespace · 44 unmodified lines
917917
918918 auto tail_maybe = list->get_tail();
919919 if (tail_maybe != nullptr)
920− tail = tail_maybe->allocation();
920+ tail = tail_maybe->get_allocation();
921921
922922 // Use the address of the local variable.
923923 r.src = reinterpret_cast<pointer_t>(&tail);
@@ -973,7 +973,7 @@ namespace · 49 unmodified lines
973973 if (type_desc->map_in_bytes > 0)
974974 vm.get_garbage_collector().track_allocation(new_channel);
975975
976− pt_ref(r.dest) = new_channel->allocation();
976+ pt_ref(r.dest) = new_channel->get_allocation();
977977 }
978978 }
979979
@@ -1061,7 +1061,7 @@ namespace · 81 unmodified lines
10611061
10621062 word_t cancel_outstanding_channel_requests(uint32_t request_thread_id, vm_alt_stack_layout_t *alt, const vm_channel_t &handled_channel)
10631063 {
1064− auto alloc = handled_channel.allocation();
1064+ auto alloc = handled_channel.get_allocation();
10651065
10661066 auto handled_index = word_t{ -1 };
10671067 const auto channel_count = (alt->send_count + alt->receive_count);
@@ -1216,7 +1216,7 @@ namespace · 148 unmodified lines
12161216 if (type_desc->map_in_bytes > 0)
12171217 vm.get_garbage_collector().track_allocation(new_alloc);
12181218
1219− pt_ref(r.dest) = new_alloc->allocation();
1219+ pt_ref(r.dest) = new_alloc->get_allocation();
12201220 }
12211221 }
12221222
@@ -1248,7 +1248,7 @@ namespace · 25 unmodified lines
12481248 if (type_desc->map_in_bytes > 0)
12491249 vm.get_garbage_collector().track_allocation(new_alloc);
12501250
1251− pt_ref(r.dest) = new_alloc->allocation();
1251+ pt_ref(r.dest) = new_alloc->get_allocation();
12521252 }
12531253
12541254 namespace
@@ -1270,7 +1270,7 @@ namespace · 15 unmodified lines
12701270 if (type_desc->map_in_bytes > 0)
12711271 vm.get_garbage_collector().track_allocation(new_array);
12721272
1273− pt_ref(r.dest) = new_array->allocation();
1273+ pt_ref(r.dest) = new_array->get_allocation();
12741274 }
12751275 }
12761276
@@ -1535,7 +1535,7 @@ namespace · 258 unmodified lines
15351535 // The first pointer in the exception is a string type
15361536 // that is used to uniquely identify the exception type.
15371537 // The remainder of the type is user-defined.
1538− auto content = e->allocation();
1538+ auto content = e->get_allocation();
15391539 exception_id = at_val<vm_string_t>(content);
15401540
15411541 if (debug::is_component_tracing_enabled<debug::component_trace_t::exception>())
@@ -1580,7 +1580,7 @@ namespace · 38 unmodified lines
15801580 dec_ref_count_and_free(current_value);
15811581
15821582 // Set the exception destination.
1583− pt_ref(exception_destination) = e->allocation();
1583+ pt_ref(exception_destination) = e->get_allocation();
15841584
15851585 r.pc = handler_pc;
15861586 }
@@ -1630,7 +1630,7 @@ namespace · 43 unmodified lines
16301630 const auto &function_imports = imports[module_import_index];
16311631
16321632 auto entry_module_ref = new vm_module_ref_t{ imported_module, function_imports };
1633− pt_ref(r.dest) = entry_module_ref->allocation();
1633+ pt_ref(r.dest) = entry_module_ref->get_allocation();
16341634 }
16351635 }
16361636
src/vm/garbage_collector.cpp+1−1
@@ -151,7 +151,7 @@ namespace · 150 unmodified lines
151151 debug::log_msg(debug::component_trace_t::garbage_collector, debug::log_level_t::debug, "gc: mark: alloc: %#" PRIxPTR "\n", curr);
152152
153153 if (curr->alloc_type->map_in_bytes > 0)
154− enum_pointer_fields(*curr->alloc_type, curr->allocation(), add_pointer_to_queue);
154+ enum_pointer_fields(*curr->alloc_type, curr->get_allocation(), add_pointer_to_queue);
155155
156156 set_gc_colour(curr, curr_colour);
157157 }
src/vm/module_reader.cpp+3−3
@@ -389,7 +389,7 @@ namespace · 388 unmodified lines
389389 auto array_stack_pointer = std::size_t{ 0 };
390390 auto success = bool{};
391391 auto code = byte_t{};
392− auto base = reinterpret_cast<byte_t *>(modobj.original_mp->allocation());
392+ auto base = reinterpret_cast<byte_t *>(modobj.original_mp->get_allocation());
393393 for (;;)
394394 {
395395 auto bytesRead = reader.get_next_bytes(sizeof(code), &code);
@@ -449,7 +449,7 @@ namespace · 53 unmodified lines
449449 throw module_reader_exception{ "Failed to read string data" };
450450
451451 auto new_string = new vm_string_t(str_buffer.size(), str_buffer.data());
452− *reinterpret_cast<pointer_t *>(data_dest) = new_string->allocation();
452+ *reinterpret_cast<pointer_t *>(data_dest) = new_string->get_allocation();
453453 break;
454454 }
455455 case datum_type_t::value_real64:
@@ -469,7 +469,7 @@ namespace · 13 unmodified lines
469469 if (!success) throw module_reader_exception{ "Failed to read word" };
470470
471471 auto new_array = new vm_array_t(modobj.type_section[element_type], element_count);
472− *reinterpret_cast<pointer_t *>(data_dest) = new_array->allocation();
472+ *reinterpret_cast<pointer_t *>(data_dest) = new_array->get_allocation();
473473 break;
474474 }
475475 case datum_type_t::set_array:
src/vm/sys/Sysmod.cpp+105−3
@@ -7,7 +7,11 @@ · 6 unmodified lines
77 #include <array>
88 #include <chrono>
99 #include <thread>
10+#include <iostream>
11+#include <fstream>
12+#include <streambuf>
1013 #include <exceptions.h>
14+#include <debug.h>
1115 #include <utf8.h>
1216 #include "Sysmod.h"
1317 #include "sys_utils.h"
@@ -73,15 +77,113 @@ std::shared_ptr<const type_descriptor_t> T_FD; · 59 unmodified lines
7377 std::shared_ptr<const type_descriptor_t> T_Connection;
7478 std::shared_ptr<const type_descriptor_t> T_FileIO;
7579
80+struct vm_fd_t final : public Sys_FD
81+{
82+ static void finalizer(vm_alloc_t *fileHandle)
83+ {
84+ auto fd = fileHandle->get_allocation<vm_fd_t>();
85+ fd->~vm_fd_t();
86+ }
87+
88+ vm_fd_t(word_t fd, std::unique_ptr<std::iostream> s)
89+ : Sys_FD{ fd }
90+ , _istream{ s.get() }
91+ , _ostream{ s.get() }
92+ {
93+ assert(s != nullptr);
94+ _stream = std::move(s);
95+ }
96+
97+ vm_fd_t(word_t fd, std::unique_ptr<std::istream> s)
98+ : Sys_FD{ fd }
99+ , _istream{ s.get() }
100+ , _ostream{ nullptr }
101+ {
102+ assert(s != nullptr);
103+ _stream = std::move(s);
104+ }
105+
106+ vm_fd_t(word_t fd, std::unique_ptr<std::ostream> s)
107+ : Sys_FD{ fd }
108+ , _istream{ nullptr }
109+ , _ostream{ s.get() }
110+ {
111+ assert(s != nullptr);
112+ _stream = std::move(s);
113+ }
114+
115+ vm_fd_t(word_t fd, std::istream &s)
116+ : Sys_FD{ fd }
117+ , _istream{ &s }
118+ , _ostream{ nullptr }
119+ {
120+ }
121+
122+ vm_fd_t(word_t fd, std::ostream &s)
123+ : Sys_FD{ fd }
124+ , _istream{ nullptr }
125+ , _ostream{ &s }
126+ {
127+ }
128+
129+ ~vm_fd_t()
130+ {
131+ debug::assign_debug_pointer(&_istream);
132+ debug::assign_debug_pointer(&_ostream);
133+
134+ if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
135+ debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: file descriptor: %d", fd);
136+ }
137+
138+ std::istream& input() const
139+ {
140+ if (_istream == nullptr)
141+ throw vm_user_exception{ "File descriptor not open for write" };
142+
143+ return *_istream;
144+ }
145+
146+ std::ostream& output() const
147+ {
148+ if (_ostream == nullptr)
149+ throw vm_user_exception{ "File descriptor not open for read" };
150+
151+ return *_ostream;
152+ }
153+
154+private:
155+ std::istream *_istream;
156+ std::ostream *_ostream;
157+ std::unique_ptr<std::ios> _stream;
158+};
159+
160+namespace
161+{
162+ vm_alloc_t *vm_stdin = nullptr;
163+ vm_alloc_t *vm_stdout = nullptr;
164+ vm_alloc_t *vm_stderr = nullptr;
165+}
166+
76167 void
77168 Sysmodinit(void)
78169 {
79170 builtin::register_module_exports(Sys_PATH, Sysmodlen, Sysmodtab);
80171 T_Qid = type_descriptor_t::create(sizeof(Sys_Qid), sizeof(Sys_Qid_map), Sys_Qid_map);
81172 T_Dir = type_descriptor_t::create(sizeof(Sys_Dir), sizeof(Sys_Dir_map), Sys_Dir_map);
82− T_FD = type_descriptor_t::create(sizeof(Sys_FD), sizeof(Sys_FD_map), Sys_FD_map);
173+ T_FD = type_descriptor_t::create(sizeof(vm_fd_t), sizeof(Sys_FD_map), Sys_FD_map, vm_fd_t::finalizer);
83174 T_Connection = type_descriptor_t::create(sizeof(Sys_Connection), sizeof(Sys_Connection_map), Sys_Connection_map);
84175 T_FileIO = type_descriptor_t::create(sizeof(Sys_FileIO), sizeof(Sys_FileIO_map), Sys_FileIO_map);
176+
177+ // Initialize default file descriptors
178+
179+ vm_stdin = vm_alloc_t::allocate(T_FD);
180+ ::new(vm_stdin->get_allocation()) vm_fd_t{ 0, std::cin };
181+
182+ vm_stdout = vm_alloc_t::allocate(T_FD);
183+ ::new(vm_stdout->get_allocation()) vm_fd_t{ 1, std::cout };
184+
185+ vm_stderr = vm_alloc_t::allocate(T_FD);
186+ ::new(vm_stderr->get_allocation()) vm_fd_t{ 2, std::cerr };
85187 }
86188
87189 void
@@ -354,13 +456,13 @@ Sys_print(vm_registers_t &r, vm_t &vm) · 266 unmodified lines
354456 auto written = printf_to_buffer(*str, msg_args, fp_base, static_buffer.size(), static_buffer.data());
355457 if (written >= 0)
356458 {
357− std::printf(static_buffer.data());
459+ vm_stdout->get_allocation<vm_fd_t>()->output() << static_buffer.data();
358460 }
359461 else
360462 {
361463 auto dynamic_buffer = std::vector<char>(static_buffer.size() * 2);
362464 written = printf_to_dynamic_buffer(*str, msg_args, fp_base, dynamic_buffer);
363− std::printf(dynamic_buffer.data());
465+ vm_stdout->get_allocation<vm_fd_t>()->output() << static_buffer.data();
364466 }
365467
366468 *fp.ret = written;
src/vm/sys/print.cpp+1−1
@@ -4,8 +4,8 @@ · 3 unmodified lines
44 // Author: arr
55 //
66
7−#include <array>
87 #include <cinttypes>
8+#include <array>
99 #include <utf8.h>
1010 #include "sys_utils.h"
1111
src/vm/thread.cpp+5−5
@@ -28,7 +28,7 @@ namespace · 27 unmodified lines
2828 reg.src = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.source.register1);
2929 break;
3030 case address_mode_t::offset_indirect_mp:
31− reg.src = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->allocation()) + inst.source.register1);
31+ reg.src = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.source.register1);
3232 break;
3333 case address_mode_t::offset_double_indirect_fp:
3434 {
@@ -38,7 +38,7 @@ namespace · 3 unmodified lines
3838 }
3939 case address_mode_t::offset_double_indirect_mp:
4040 {
41− const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->allocation()) + inst.source.register1);
41+ const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.source.register1);
4242 reg.src = reinterpret_cast<pointer_t>(mp_offset + inst.source.register2);
4343 break;
4444 }
@@ -58,7 +58,7 @@ namespace · 13 unmodified lines
5858 reg.dest = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.destination.register1);
5959 break;
6060 case address_mode_t::offset_indirect_mp:
61− reg.dest = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->allocation()) + inst.destination.register1);
61+ reg.dest = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.destination.register1);
6262 break;
6363 case address_mode_t::offset_double_indirect_fp:
6464 {
@@ -68,7 +68,7 @@ namespace · 3 unmodified lines
6868 }
6969 case address_mode_t::offset_double_indirect_mp:
7070 {
71− const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->allocation()) + inst.destination.register1);
71+ const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.destination.register1);
7272 reg.dest = reinterpret_cast<pointer_t>(mp_offset + inst.destination.register2);
7373 break;
7474 }
@@ -88,7 +88,7 @@ namespace · 13 unmodified lines
8888 reg.mid = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.middle.register1);
8989 break;
9090 case address_mode_middle_t::small_offset_indirect_mp:
91− reg.mid = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->allocation()) + inst.middle.register1);
91+ reg.mid = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.middle.register1);
9292 break;
9393 case address_mode_middle_t::small_immediate:
9494 reg.mid = reinterpret_cast<pointer_t>(const_cast<word_t *>(&inst.middle.register1));
src/vm/vm_memory.cpp+5−5
@@ -230,7 +230,7 @@ vm_alloc_t *vm_alloc_t::allocate(std::shared_ptr<const type_descriptor_t> td) · 229 unmodified lines
230230 auto alloc = ::new(mem)vm_alloc_t{ td };
231231
232232 // Initialize pointer types
233− init_memory(*td, alloc->allocation());
233+ init_memory(*td, alloc->get_allocation());
234234
235235 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm alloc: %d\n", td->size_in_bytes);
236236 return alloc;
@@ -255,10 +255,10 @@ vm_alloc_t *vm_alloc_t::copy(const vm_alloc_t &other) · 18 unmodified lines
255255 auto alloc_copy = vm_alloc_t::allocate(other.alloc_type);
256256
257257 // Copy the current memory contents of the allocation
258− std::memcpy(alloc_copy->allocation(), other.allocation(), alloc_copy->alloc_type->size_in_bytes);
258+ std::memcpy(alloc_copy->get_allocation(), other.get_allocation(), alloc_copy->alloc_type->size_in_bytes);
259259
260260 // Ref count all dynamic allocations
261− inc_ref_count_in_memory(*alloc_copy->alloc_type, alloc_copy->allocation());
261+ inc_ref_count_in_memory(*alloc_copy->alloc_type, alloc_copy->get_allocation());
262262
263263 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "copy: vm alloc: %#" PRIxPTR " %#" PRIxPTR "\n", &other, alloc_copy);
264264 return alloc_copy;
@@ -289,7 +289,7 @@ vm_alloc_t::~vm_alloc_t() · 24 unmodified lines
289289 finalizer(this);
290290
291291 // Free pointer types
292− destroy_memory(*alloc_type, allocation());
292+ destroy_memory(*alloc_type, get_allocation());
293293 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm alloc\n");
294294 }
295295
@@ -314,7 +314,7 @@ std::size_t vm_alloc_t::get_ref_count() const · 18 unmodified lines
314314 return _ref_count;
315315 }
316316
317−pointer_t vm_alloc_t::allocation() const
317+pointer_t vm_alloc_t::get_allocation() const
318318 {
319319 // Remove const on the this pointer so the offset can be computed.
320320 auto non_const_this = const_cast<vm_alloc_t *>(this);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t