コミットメタ情報
ログメッセージ
Fix use of circular packages
変更サマリ
差分
| | @@ -2371,7 +2371,7 @@ | 2371 | 2371 | call_n (interp, 0); | 2372 | 2372 | | 2373 | 2373 | // Add a 'POP' instruction to mantain the stack size consistent. | 2374 | | - bvector *bvp = as_bvector(retp->bcode); | | 2374 | + bvector *bvp = as_bvector (retp->bcode); | 2375 | 2375 | bvp->data[bvp->nbytes - 1] = OP_POP; | 2376 | 2376 | bytecode.add_data (bvp->data, bvp->nbytes); | 2377 | 2377 | |
| | @@ -599,6 +599,16 @@ | 599 | 599 | } | 600 | 600 | } | 601 | 601 | | | 602 | +static inline void | | 603 | +register_pkg (package *p, dlist *node) | | 604 | +{ | | 605 | + dlist *lp = &p->pkg_link; | | 606 | + lp->next = node; | | 607 | + lp->prev = node->prev; | | 608 | + node->prev->next = lp; | | 609 | + node->prev = lp; | | 610 | +} | | 611 | + | 602 | 612 | struct import_data | 603 | 613 | { | 604 | 614 | static const uint32_t only_qpfiles = 1; |
| | @@ -614,6 +624,7 @@ | 614 | 624 | uint32_t flags = 0; | 615 | 625 | char *canonical_path = nullptr; | 616 | 626 | int path_len; | | 627 | + package *rpkg = nullptr; | 617 | 628 | | 618 | 629 | import_data (interpreter *ip) : interp (ip), | 619 | 630 | dir (ip, UNBOUND), strm (ip, UNBOUND), |
| | @@ -630,13 +641,24 @@ | 630 | 641 | if (*this->prev != UNBOUND) | 631 | 642 | this->interp->xpkg = *this->prev; | 632 | 643 | this->release_path (); | | 644 | + | | 645 | + if (this->rpkg != nullptr) | | 646 | + this->rpkg->pkg_link.del (); | 633 | 647 | } | 634 | 648 | | 635 | | - void set_pkg (object pkg) | | 649 | + object set_pkg (package *p, dlist *node) | 636 | 650 | { | | 651 | + if (!node) | | 652 | + { | | 653 | + this->rpkg = nullptr; | | 654 | + return (p->as_obj ()); | | 655 | + } | | 656 | + | 637 | 657 | *this->prev = this->interp->xpkg; | 638 | | - as_package(pkg)->path = *this->dir; | 639 | | - this->interp->xpkg = pkg; | | 658 | + p->path = *this->dir; | | 659 | + this->interp->xpkg = p->as_obj (); | | 660 | + register_pkg (this->rpkg = p, node); | | 661 | + return (UNBOUND); | 640 | 662 | } | 641 | 663 | | 642 | 664 | void release_path () |
| | @@ -746,7 +768,8 @@ | 746 | 768 | (len > 3 && sp[1] == '.' && sp[2] == '/'))) | 747 | 769 | { // Path is relative to current directory. | 748 | 770 | relative: | 749 | | - bool ret = data.open (sp, len, as_package(interp->xpkg)->path); | | 771 | + bool ret = data.open (sp, len, | | 772 | + *data.dir = as_package(interp->xpkg)->path); | 750 | 773 | | 751 | 774 | if (ret) | 752 | 775 | { |
| | @@ -813,17 +836,6 @@ | 813 | 836 | return (nullptr); | 814 | 837 | } | 815 | 838 | | 816 | | -static inline object | 817 | | -register_pkg (object pkg, const char *path, int len, dlist *node) | 818 | | -{ | 819 | | - dlist *lp = &as_package(pkg)->pkg_link; | 820 | | - lp->next = node; | 821 | | - lp->prev = node->prev; | 822 | | - node->prev->next = lp; | 823 | | - node->prev = lp; | 824 | | - return (pkg); | 825 | | -} | 826 | | - | 827 | 839 | static object | 828 | 840 | import_pkg_lk (interpreter *interp, object path, object name, import_data& dt) | 829 | 841 | { |
| | @@ -852,19 +864,18 @@ | 852 | 864 | { // Found a compiled package. | 853 | 865 | fstream_stat st1, st2; | 854 | 866 | | 855 | | - if ((*dt.strm == UNBOUND || | | 867 | + if (*dt.strm == UNBOUND || | 856 | 868 | (fstream_fstat (as_stream (*dt.strm), st1) && | 857 | 869 | fstream_fstat (as_stream (*dt.qpc), st2) && | 858 | | - st1.mtime <= st2.mtime))) | | 870 | + st1.mtime <= st2.mtime && st2.mtime != st2.ctime)) | 859 | 871 | { // The compiled package is up to date. | 860 | 872 | object expr = xdeserialize (interp, as_stream (*dt.qpc), sin); | 861 | 873 | if (fct_p (expr)) | 862 | 874 | { | 863 | | - dt.set_pkg (*ret); | | 875 | + dt.set_pkg (p, node); | 864 | 876 | interp->push (expr); | 865 | 877 | call_n (interp, 0); | 866 | | - qp_return (register_pkg (*ret, p->canonical_path, | 867 | | - p->path_len, node)); | | 878 | + qp_return (dt.set_pkg (p, nullptr)); | 868 | 879 | } | 869 | 880 | } | 870 | 881 | } |
| | @@ -874,7 +885,7 @@ | 874 | 885 | | 875 | 886 | reader rd (interp, *dt.strm, as_package (*ret)); | 876 | 887 | // Switch packages before executing any code. | 877 | | - dt.set_pkg (*ret); | | 888 | + dt.set_pkg (p, node); | 878 | 889 | | 879 | 890 | // Compile the package and (optionally) serialize it. | 880 | 891 | object expr = compile_pkg (interp, rd); |
| | @@ -883,7 +894,7 @@ | 883 | 894 | fstream_truncate (interp, as_stream (*dt.qpc), 0)) | 884 | 895 | xserialize (interp, as_stream (*dt.qpc), expr, sin); | 885 | 896 | | 886 | | - qp_return (register_pkg (*ret, p->canonical_path, p->path_len, node)); | | 897 | + qp_return (dt.set_pkg (p, nullptr)); | 887 | 898 | } | 888 | 899 | | 889 | 900 | object import_pkg (interpreter *interp, object path, object name) |
| | @@ -16,8 +16,8 @@ | 16 | 16 | return (ret); | 17 | 17 | } | 18 | 18 | | 19 | | -static inline | 20 | | -timespec tstamp2tspec (double dbl) | | 19 | +static inline timespec | | 20 | +tstamp2tspec (double dbl) | 21 | 21 | { | 22 | 22 | timespec ret; | 23 | 23 | |
旧リポジトリブラウザで表示
|