(
target: Pointer,
start: number,
deleteCount: number,
items: any[] = [],
)
| 1121 | } |
| 1122 | |
| 1123 | private arraySpliceImpl( |
| 1124 | target: Pointer, |
| 1125 | start: number, |
| 1126 | deleteCount: number, |
| 1127 | items: any[] = [], |
| 1128 | ): any[] { |
| 1129 | this.resolvePtr(target.__ptr); |
| 1130 | const len = this.scratchLen; |
| 1131 | const actualStart = start < 0 |
| 1132 | ? Math.max(len + start, 0) |
| 1133 | : Math.min(start, len); |
| 1134 | const actualDeleteCount = Math.min( |
| 1135 | Math.max(deleteCount, 0), |
| 1136 | len - actualStart, |
| 1137 | ); |
| 1138 | |
| 1139 | // 1. Read deleted items to return |
| 1140 | const deletedItems: any[] = []; |
| 1141 | for (let i = 0; i < actualDeleteCount; i++) { |
| 1142 | const offset = this.scratchStart + (actualStart + i) * 8; |
| 1143 | deletedItems.push(this.readSlot(offset)); |
| 1144 | } |
| 1145 | |
| 1146 | const insertCount = items.length; |
| 1147 | const delta = insertCount - actualDeleteCount; |
| 1148 | const newLen = len + delta; |
| 1149 | |
| 1150 | // 2. Ensure Capacity (Allocates new buffer if needed) |
| 1151 | this.arrayEnsureCapacity(target, newLen); |
| 1152 | // After this, this.s_start, s_ptr, s_cap are updated to potentially new location |
| 1153 | |
| 1154 | // 3. Move Memory (Shift tail) |
| 1155 | if (delta !== 0) { |
| 1156 | const tailCount = len - (actualStart + actualDeleteCount); |
| 1157 | const srcIdx = actualStart + actualDeleteCount; |
| 1158 | const destIdx = actualStart + insertCount; |
| 1159 | |
| 1160 | const srcOffset = this.scratchStart + srcIdx * 8; |
| 1161 | const destOffset = this.scratchStart + destIdx * 8; |
| 1162 | const byteLen = tailCount * 8; |
| 1163 | |
| 1164 | this.u8.copyWithin(destOffset, srcOffset, srcOffset + byteLen); |
| 1165 | } |
| 1166 | |
| 1167 | // 4. Insert Items |
| 1168 | for (let i = 0; i < insertCount; i++) { |
| 1169 | const val = items[i]; |
| 1170 | const valResult = this.writeValue(val); |
| 1171 | const valHandle = { __ptr: valResult.payload }; |
| 1172 | const isValPtr = valResult.type >= TYPE_NUMBER; |
| 1173 | |
| 1174 | if (isValPtr) { |
| 1175 | this.tempRoots.push({ handle: valHandle, type: valResult.type }); |
| 1176 | } |
| 1177 | |
| 1178 | this.resolvePtr(target.__ptr); |
| 1179 | const offset = this.scratchStart + (actualStart + i) * 8; |
| 1180 | const oIdx = offset >> 2; |
no test coverage detected