History

Implement seek() utfbytes() in Sys module. - Updated tests for utfbytes() - Updated utf8 API surface to support the general length case (codepoint _and_ byte) - Testing of seek() still outstanding Comment added regarding stack frame pointer in stack frames.

arr committed 9 years ago

Commit a6da1dc1 parent 1af55286 files · +94 −18Browse files

Showing the changes to src/vm/sys/Sysmod.cpp (1 of 6 files). Show all

Unified · Split

src/vm/sys/Sysmod.cpp+57−4
@@ -188,6 +188,15 @@ namespace · 187 unmodified lines
188 throw vm_user_exception{ "Write operation error" };188 throw vm_user_exception{ "Write operation error" };
189 }189 }
190 190
191 big_t seek(const std::ios::seekdir start, const big_t offset)
192 {
193 if (_stream == nullptr)
194 throw vm_user_exception{ "Unable to seek on a fifo file descriptor (e.g. stdin, stdout, stderr)" };
195
196 auto new_offset = _stream->rdbuf()->pubseekoff(static_cast<std::streamoff>(offset), start, _fd_mode);
197 return static_cast<big_t>(new_offset);
198 }
199
191 private:200 private:
192 const word_t _fd_mode;201 const word_t _fd_mode;
193 vm_string_t *_fd_path;202 vm_string_t *_fd_path;
@@ -218,6 +227,21 @@ namespace · 24 unmodified lines
218 227
219 return om;228 return om;
220 }229 }
230
231 std::ios::seekdir convert_to_seekdir(const word_t start)
232 {
233 switch (start)
234 {
235 case Sys_SEEKSTART:
236 return std::ios::beg;
237 case Sys_SEEKRELA:
238 return std::ios::cur;
239 case Sys_SEEKEND:
240 return std::ios::end;
241 default:
242 throw vm_user_exception{ "Invalid seek mode" };
243 }
244 }
221}245}
222 246
223void247void
@@ -612,7 +636,6 @@ Sys_read(vm_registers_t &r, vm_t &vm) · 388 unmodified lines
612 auto &fp = r.stack.peek_frame()->base<F_Sys_read>();636 auto &fp = r.stack.peek_frame()->base<F_Sys_read>();
613 637
614 const auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.buf);638 const auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.buf);
615 assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
616 639
617 auto n = fp.n;640 auto n = fp.n;
618 if (buffer == nullptr || n <= 0)641 if (buffer == nullptr || n <= 0)
@@ -621,11 +644,16 @@ Sys_read(vm_registers_t &r, vm_t &vm) · 2 unmodified lines
621 return;644 return;
622 }645 }
623 646
647 assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
648
624 // [SPEC] Supplying a size greater than the buffer length is649 // [SPEC] Supplying a size greater than the buffer length is
625 // equivalent to indicating the entire buffer should be filled.650 // equivalent to indicating the entire buffer should be filled.
626 n = std::min(n, buffer->get_length());651 n = std::min(n, buffer->get_length());
627 652
628 auto fd_alloc = vm_alloc_t::from_allocation(fp.fd);653 auto fd_alloc = vm_alloc_t::from_allocation(fp.fd);
654 if (fd_alloc == nullptr)
655 throw dereference_nil{ "Read from file descriptor" };
656
629 assert(fd_alloc->alloc_type == T_FD);657 assert(fd_alloc->alloc_type == T_FD);
630 658
631 auto fd = fd_alloc->get_allocation<vm_fd_t>();659 auto fd = fd_alloc->get_allocation<vm_fd_t>();
@@ -650,7 +678,16 @@ void · 18 unmodified lines
650Sys_seek(vm_registers_t &r, vm_t &vm)678Sys_seek(vm_registers_t &r, vm_t &vm)
651{679{
652 auto &fp = r.stack.peek_frame()->base<F_Sys_seek>();680 auto &fp = r.stack.peek_frame()->base<F_Sys_seek>();
653 throw vm_system_exception{ "Instruction not implemented" };681
682 auto fd_alloc = vm_alloc_t::from_allocation(fp.fd);
683 if (fd_alloc == nullptr)
684 throw dereference_nil{ "Seek in file descriptor" };
685
686 assert(fd_alloc->alloc_type == T_FD);
687 auto fd = fd_alloc->get_allocation<vm_fd_t>();
688
689 const auto start = convert_to_seekdir(fp.start);
690 *fp.ret = fd->seek(start, fp.off);
654}691}
655 692
656void693void
@@ -814,7 +851,19 @@ void · 157 unmodified lines
814Sys_utfbytes(vm_registers_t &r, vm_t &vm)851Sys_utfbytes(vm_registers_t &r, vm_t &vm)
815{852{
816 auto &fp = r.stack.peek_frame()->base<F_Sys_utfbytes>();853 auto &fp = r.stack.peek_frame()->base<F_Sys_utfbytes>();
817 throw vm_system_exception{ "Instruction not implemented" };854 const auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.buf);
855
856 const auto n = fp.n;
857 if (buffer == nullptr || n > buffer->get_length())
858 throw out_of_range_memory{};
859
860 assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
861
862 auto raw_buffer = reinterpret_cast<uint8_t *>(buffer->at(0));
863
864 const auto len = utf8::count_codepoints(raw_buffer, n);
865 *fp.ret = static_cast<word_t>(len.byte_count);
866 assert(*fp.ret <= n && "Code points should not exceed number of bytes processed");
818}867}
819 868
820void869void
@@ -830,7 +879,6 @@ Sys_write(vm_registers_t &r, vm_t &vm) · 9 unmodified lines
830 auto &fp = r.stack.peek_frame()->base<F_Sys_write>();879 auto &fp = r.stack.peek_frame()->base<F_Sys_write>();
831 880
832 const auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.buf);881 const auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.buf);
833 assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
834 882
835 auto n = fp.n;883 auto n = fp.n;
836 if (buffer == nullptr || n <= 0)884 if (buffer == nullptr || n <= 0)
@@ -839,11 +887,16 @@ Sys_write(vm_registers_t &r, vm_t &vm) · 2 unmodified lines
839 return;887 return;
840 }888 }
841 889
890 assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
891
842 // [SPEC] Supplying a size greater than the buffer length is892 // [SPEC] Supplying a size greater than the buffer length is
843 // equivalent to indicating the entire buffer should be written.893 // equivalent to indicating the entire buffer should be written.
844 n = std::min(n, buffer->get_length());894 n = std::min(n, buffer->get_length());
845 895
846 auto fd_alloc = vm_alloc_t::from_allocation(fp.fd);896 auto fd_alloc = vm_alloc_t::from_allocation(fp.fd);
897 if (fd_alloc == nullptr)
898 throw dereference_nil{ "Write to file descriptor" };
899
847 assert(fd_alloc->alloc_type == T_FD);900 assert(fd_alloc->alloc_type == T_FD);
848 901
849 auto fd = fd_alloc->get_allocation<vm_fd_t>();902 auto fd = fd_alloc->get_allocation<vm_fd_t>();