MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

safe entry fp for engine

+57 -9
+57 -9
src/silver/engine.c
··· 36 36 if (!vm) return NULL; 37 37 38 38 vm->js = js; 39 + vm->fp = -1; 40 + 39 41 vm->stack_size = stack_size; 40 - vm->stack = calloc((size_t)stack_size, sizeof(ant_value_t)); 41 42 vm->max_frames = max_frames; 43 + 44 + vm->suspended_entry_fp = -1; 45 + vm->suspended_saved_fp = -1; 46 + 47 + vm->stack = calloc((size_t)stack_size, sizeof(ant_value_t)); 42 48 vm->frames = calloc((size_t)max_frames, sizeof(sv_frame_t)); 43 - if (!vm->stack || !vm->frames) { sv_vm_destroy(vm); return NULL; } 49 + 50 + if (!vm->stack || !vm->frames) { 51 + sv_vm_destroy(vm); 52 + return NULL; 53 + } 44 54 45 55 return vm; 46 56 } ··· 1698 1708 1699 1709 L_AWAIT: { 1700 1710 ant_value_t await_val = vm->stack[--vm->sp]; 1711 + frame->ip = ip + 1; 1712 + vm->suspended_entry_fp = entry_fp; 1713 + vm->suspended_saved_fp = entry_fp - 1; 1714 + 1701 1715 ant_value_t result = sv_await_value(js, await_val); 1702 - if (vm->suspended) { 1703 - vm->suspended_entry_fp = entry_fp; 1704 - vm->suspended_saved_fp = entry_fp - 1; 1705 - frame->ip = ip + 1; 1706 - goto sv_leave; 1716 + if (vm->suspended) goto sv_leave; 1717 + 1718 + vm->suspended_entry_fp = -1; 1719 + vm->suspended_saved_fp = -1; 1720 + 1721 + if (is_err(result)) { 1722 + sv_err = result; 1723 + goto sv_throw; 1707 1724 } 1708 - if (is_err(result)) { sv_err = result; goto sv_throw; } 1725 + 1709 1726 vm->stack[vm->sp++] = result; 1710 1727 NEXT(1); 1711 1728 } ··· 1726 1743 vm_result = yielded; 1727 1744 goto sv_leave; 1728 1745 } 1746 + 1729 1747 L_YIELD_STAR_INIT: { 1730 1748 uint16_t base = sv_get_u16(ip + 1); 1731 1749 ant_value_t iterable = vm->stack[--vm->sp]; ··· 1877 1895 if (!vm || !vm->suspended || !vm->suspended_resume_pending || vm->fp < 0) 1878 1896 return mkval(T_ERR, 0); 1879 1897 1898 + // crash-resistance for missing frames 1899 + if (vm->suspended_entry_fp < 0 || vm->suspended_entry_fp > vm->fp) { 1900 + vm->suspended = false; 1901 + vm->suspended_resume_pending = false; 1902 + vm->suspended_resume_is_error = false; 1903 + vm->suspended_resume_kind = SV_RESUME_NEXT; 1904 + vm->suspended_resume_value = js_mkundef(); 1905 + vm->suspended_entry_fp = -1; 1906 + vm->suspended_saved_fp = -1; 1907 + 1908 + return vm->js 1909 + ? js_mkerr(vm->js, "invalid suspended entry frame") 1910 + : mkval(T_ERR, 0); 1911 + } 1912 + 1880 1913 int saved_fp = vm->suspended_saved_fp; 1881 1914 sv_frame_t *frame = &vm->frames[vm->fp]; 1915 + 1916 + if (!vm->js || !frame->func || !frame->ip) { 1917 + vm->suspended = false; 1918 + vm->suspended_resume_pending = false; 1919 + vm->suspended_resume_is_error = false; 1920 + vm->suspended_resume_kind = SV_RESUME_NEXT; 1921 + vm->suspended_resume_value = js_mkundef(); 1922 + vm->suspended_entry_fp = -1; 1923 + vm->suspended_saved_fp = -1; 1924 + 1925 + return vm->js 1926 + ? js_mkerr(vm->js, "invalid suspended frame state") 1927 + : mkval(T_ERR, 0); 1928 + } 1929 + 1882 1930 ant_value_t result = sv_execute_frame( 1883 1931 vm, frame->func, frame->this, frame->super_val, NULL, frame->argc 1884 1932 ); 1885 1933 1886 1934 if (!vm->suspended) { 1887 1935 vm->fp = saved_fp; 1888 - vm->suspended_entry_fp = 0; 1936 + vm->suspended_entry_fp = -1; 1889 1937 vm->suspended_saved_fp = -1; 1890 1938 } 1891 1939