aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd2023-07-25 12:16:30 +0200
committerMattias EngdegÄrd2023-07-26 17:34:03 +0200
commit82f5f3b8a26249db0679bb7dc38c44352e8fbdf5 (patch)
tree5890c3bec8dd65921695dd52949545cf21e92707 /src/bytecode.c
parentc50f6538cfc43d856b361347c945f6348c6f2dc9 (diff)
downloademacs-82f5f3b8a26249db0679bb7dc38c44352e8fbdf5.tar.gz
emacs-82f5f3b8a26249db0679bb7dc38c44352e8fbdf5.zip
Provide backtrace for byte-ops aref and aset
Produce synthetic backtrace entries for `aref` and `aset` byte-ops when the index is non-fixnum, or is out of range for vector or record arguments (bug#64613). * src/bytecode.c (exec_byte_code): Detect type and range errors in-line for aref and aset. * src/data.c (syms_of_data): Declare symbols Qaref and Qaset. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--byte-op-error-cases): Add test cases.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 2eb53b0428a..c53ef678edd 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1115,14 +1115,24 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
1115 { 1115 {
1116 Lisp_Object idxval = POP; 1116 Lisp_Object idxval = POP;
1117 Lisp_Object arrayval = TOP; 1117 Lisp_Object arrayval = TOP;
1118 if (!FIXNUMP (idxval))
1119 {
1120 record_in_backtrace (Qaref, &TOP, 2);
1121 wrong_type_argument (Qfixnump, idxval);
1122 }
1118 ptrdiff_t size; 1123 ptrdiff_t size;
1119 ptrdiff_t idx;
1120 if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true)) 1124 if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true))
1121 || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))) 1125 || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))))
1122 && FIXNUMP (idxval) 1126 {
1123 && (idx = XFIXNUM (idxval), 1127 ptrdiff_t idx = XFIXNUM (idxval);
1124 idx >= 0 && idx < size)) 1128 if (idx >= 0 && idx < size)
1125 TOP = AREF (arrayval, idx); 1129 TOP = AREF (arrayval, idx);
1130 else
1131 {
1132 record_in_backtrace (Qaref, &TOP, 2);
1133 args_out_of_range (arrayval, idxval);
1134 }
1135 }
1126 else 1136 else
1127 TOP = Faref (arrayval, idxval); 1137 TOP = Faref (arrayval, idxval);
1128 NEXT; 1138 NEXT;
@@ -1133,16 +1143,26 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
1133 Lisp_Object newelt = POP; 1143 Lisp_Object newelt = POP;
1134 Lisp_Object idxval = POP; 1144 Lisp_Object idxval = POP;
1135 Lisp_Object arrayval = TOP; 1145 Lisp_Object arrayval = TOP;
1146 if (!FIXNUMP (idxval))
1147 {
1148 record_in_backtrace (Qaset, &TOP, 3);
1149 wrong_type_argument (Qfixnump, idxval);
1150 }
1136 ptrdiff_t size; 1151 ptrdiff_t size;
1137 ptrdiff_t idx;
1138 if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true)) 1152 if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true))
1139 || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))) 1153 || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))))
1140 && FIXNUMP (idxval)
1141 && (idx = XFIXNUM (idxval),
1142 idx >= 0 && idx < size))
1143 { 1154 {
1144 ASET (arrayval, idx, newelt); 1155 ptrdiff_t idx = XFIXNUM (idxval);
1145 TOP = newelt; 1156 if (idx >= 0 && idx < size)
1157 {
1158 ASET (arrayval, idx, newelt);
1159 TOP = newelt;
1160 }
1161 else
1162 {
1163 record_in_backtrace (Qaset, &TOP, 3);
1164 args_out_of_range (arrayval, idxval);
1165 }
1146 } 1166 }
1147 else 1167 else
1148 TOP = Faset (arrayval, idxval, newelt); 1168 TOP = Faset (arrayval, idxval, newelt);