diff --git a/Sources/Fuzzilli/Core/CodeGenerators.swift b/Sources/Fuzzilli/Core/CodeGenerators.swift
index e3150aa47..f1074b303 100644
--- a/Sources/Fuzzilli/Core/CodeGenerators.swift
+++ b/Sources/Fuzzilli/Core/CodeGenerators.swift
@@ -393,6 +393,32 @@ public let CodeGenerators: [CodeGenerator] = [
         b.reassign(target, to: val)
     },
 
+    CodeGenerator("DestructArrayGenerator", input: .iterable) { b, arr in
+        // Fuzzilli generated arrays can have a length ranging from 0 to 10 elements,
+        // We want to ensure that 1) when destructing arrays we are usually within this length range
+        // and 2) The probability with which we select indices allows defining atleast 2-3 variables.
+        var indices: [Int] = []
+        for idx in 0..<Int.random(in: 0..<5) {
+            withProbability(0.7) {
+                indices.append(idx)
+            }
+        }
+
+        b.destruct(arr, selecting: indices, hasRestElement: probability(0.2))
+    },
+
+    CodeGenerator("DestructArrayAndReassignGenerator", input: .iterable) {b, arr in
+        var candidates: [Variable] = []
+        var indices: [Int] = []
+        for idx in 0..<Int.random(in: 0..<5) {
+            withProbability(0.7) {
+                indices.append(idx)
+                candidates.append(b.randVar())
+            }
+        }
+        b.destruct(arr, selecting: indices, into: candidates, hasRestElement: probability(0.2))
+    },
+
     CodeGenerator("ComparisonGenerator", inputs: (.anything, .anything)) { b, lhs, rhs in
         b.compare(lhs, rhs, with: chooseUniform(from: allComparators))
     },
diff --git a/Sources/Fuzzilli/Core/ProgramBuilder.swift b/Sources/Fuzzilli/Core/ProgramBuilder.swift
index 978c15629..96f62d3d5 100644
--- a/Sources/Fuzzilli/Core/ProgramBuilder.swift
+++ b/Sources/Fuzzilli/Core/ProgramBuilder.swift
@@ -1309,6 +1309,16 @@ public class ProgramBuilder {
         perform(Reassign(), withInputs: [output, input])
     }
 
+    @discardableResult
+    public func destruct(_ input: Variable, selecting indices: [Int], hasRestElement: Bool = false) -> [Variable] {
+        let outputs = perform(DestructArray(indices: indices, hasRestElement: hasRestElement), withInputs: [input]).outputs
+        return Array(outputs)
+    }
+
+    public func destruct(_ input: Variable, selecting indices: [Int], into outputs: [Variable], hasRestElement: Bool) {
+        perform(DestructArrayAndReassign(indices: indices, hasRestElement: hasRestElement), withInputs: [input] + outputs)
+    }
+
     @discardableResult
     public func compare(_ lhs: Variable, _ rhs: Variable, with comparator: Comparator) -> Variable {
         return perform(Compare(comparator), withInputs: [lhs, rhs]).output
diff --git a/Sources/Fuzzilli/FuzzIL/AbstractInterpreter.swift b/Sources/Fuzzilli/FuzzIL/AbstractInterpreter.swift
index b1702b818..04dce8bff 100644
--- a/Sources/Fuzzilli/FuzzIL/AbstractInterpreter.swift
+++ b/Sources/Fuzzilli/FuzzIL/AbstractInterpreter.swift
@@ -476,6 +476,12 @@ public struct AbstractInterpreter {
         case is Reassign:
             set(instr.input(0), type(ofInput: 1))
 
+        case is DestructArray:
+            instr.outputs.forEach{set($0, .unknown)}
+
+        case is DestructArrayAndReassign:
+            instr.inputs.dropFirst().forEach{set($0, .unknown)}
+
         case is Compare:
             set(instr.output, .boolean)
 
diff --git a/Sources/Fuzzilli/FuzzIL/Instruction.swift b/Sources/Fuzzilli/FuzzIL/Instruction.swift
index d462ff9fa..b40413164 100644
--- a/Sources/Fuzzilli/FuzzIL/Instruction.swift
+++ b/Sources/Fuzzilli/FuzzIL/Instruction.swift
@@ -411,6 +411,16 @@ extension Instruction: ProtobufConvertible {
                 $0.dup = Fuzzilli_Protobuf_Dup()
             case is Reassign:
                 $0.reassign = Fuzzilli_Protobuf_Reassign()
+            case let op as DestructArray:
+                $0.destructArray = Fuzzilli_Protobuf_DestructArray.with { 
+                    $0.indices = op.indices.map({ Int32($0) })
+                    $0.hasRestElement_p = op.hasRestElement
+                }
+            case let op as DestructArrayAndReassign:
+                $0.destructArrayAndReassign = Fuzzilli_Protobuf_DestructArrayAndReassign.with {
+                    $0.indices = op.indices.map({ Int32($0) })
+                    $0.hasRestElement_p = op.hasRestElement 
+                }
             case let op as Compare:
                 $0.compare = Fuzzilli_Protobuf_Compare.with { $0.op = convertEnum(op.op, allComparators) }
             case is ConditionalOperation:
@@ -658,6 +668,10 @@ extension Instruction: ProtobufConvertible {
             op = Dup()
         case .reassign(_):
             op = Reassign()
+        case .destructArray(let p):
+            op = DestructArray(indices: p.indices.map({ Int($0) }), hasRestElement: p.hasRestElement_p)
+        case .destructArrayAndReassign(let p):
+            op = DestructArrayAndReassign(indices: p.indices.map({ Int($0) }), hasRestElement: p.hasRestElement_p)
         case .compare(let p):
             op = Compare(try convertEnum(p.op, allComparators))
         case .conditionalOperation(_):
diff --git a/Sources/Fuzzilli/FuzzIL/Operations.swift b/Sources/Fuzzilli/FuzzIL/Operations.swift
index f4fedf93c..0558ec28e 100644
--- a/Sources/Fuzzilli/FuzzIL/Operations.swift
+++ b/Sources/Fuzzilli/FuzzIL/Operations.swift
@@ -653,6 +653,35 @@ class Reassign: Operation {
     }
 }
 
+/// Destructs an array into n output variables
+class DestructArray: Operation {
+    let indices: [Int]
+    let hasRestElement: Bool
+    
+    init(indices: [Int], hasRestElement: Bool) {
+        assert(indices == indices.sorted(), "Indices must be sorted in ascending order")
+        assert(indices.count == Set(indices).count, "Indices must not have duplicates")
+        self.hasRestElement = hasRestElement
+        self.indices = indices
+        super.init(numInputs: 1, numOutputs: indices.count)
+    }
+}
+
+/// Destructs an array and reassigns the output to n existing variables
+class DestructArrayAndReassign: Operation {
+    let indices: [Int]
+    let hasRestElement: Bool
+
+    init(indices: [Int], hasRestElement:Bool) {
+        assert(indices == indices.sorted(), "Indices must be sorted in ascending order")
+        assert(indices.count == Set(indices).count, "Indices must not have duplicates")
+        self.indices = indices
+        self.hasRestElement = hasRestElement
+        // The first input is the array being destructed
+        super.init(numInputs: 1 + indices.count, numOutputs: 0)
+    }
+}
+
 // This array must be kept in sync with the Comparator Enum in operations.proto
 public enum Comparator: String {
     case equal              = "=="
diff --git a/Sources/Fuzzilli/FuzzIL/Semantics.swift b/Sources/Fuzzilli/FuzzIL/Semantics.swift
index 0e7de20a7..5e9c11af3 100644
--- a/Sources/Fuzzilli/FuzzIL/Semantics.swift
+++ b/Sources/Fuzzilli/FuzzIL/Semantics.swift
@@ -49,6 +49,8 @@ extension Operation {
             return inputIdx == 0
         case let op as UnaryOperation:
             return op.op.reassignsInput
+        case is DestructArrayAndReassign:
+            return inputIdx != 0
         default:
             return false
         }
diff --git a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift
index 17f68dcbc..c3966e73f 100644
--- a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift
+++ b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift
@@ -24,6 +24,22 @@ public class FuzzILLifter: Lifter {
             return instr.input(n)
         }
 
+        // Helper function to lift destruct array operations
+        func liftArrayPattern(indices: [Int], outputs: [String], hasRestElement: Bool) -> String {
+            assert(indices.count == outputs.count)
+
+            var arrayPattern = ""
+            var lastIndex = 0
+            for (index, output) in zip(indices, outputs) {
+                let skipped = index - lastIndex
+                lastIndex = index
+                let dots = index == indices.last! && hasRestElement ? "..." : ""
+                arrayPattern += String(repeating: ",", count: skipped) + dots + output
+            }
+
+            return arrayPattern
+        }
+
         switch instr.op {
         case let op as LoadInteger:
             w.emit("\(instr.output) <- LoadInteger '\(op.value)'")
@@ -229,6 +245,14 @@ public class FuzzILLifter: Lifter {
         case is Reassign:
             w.emit("Reassign \(input(0)), \(input(1))")
 
+        case let op as DestructArray:
+            let outputs = instr.outputs.map({ $0.identifier })
+            w.emit("[\(liftArrayPattern(indices: op.indices, outputs: outputs, hasRestElement: op.hasRestElement))] <- DestructArray \(input(0))")
+
+        case let op as DestructArrayAndReassign:
+            let outputs = instr.inputs.dropFirst().map({ $0.identifier })        
+            w.emit("[\(liftArrayPattern(indices: op.indices, outputs: outputs, hasRestElement: op.hasRestElement))] <- DestructArrayAndReassign \(input(0))")
+
         case let op as Compare:
             w.emit("\(instr.output) <- Compare \(input(0)), '\(op.op.token)', \(input(1))")
 
diff --git a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift
index 5fb5300ec..e45b170c1 100644
--- a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift
+++ b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift
@@ -115,6 +115,22 @@ public class JavaScriptLifter: Lifter {
                 return expr(for: instr.input(idx))
             }
 
+            // Helper function to lift destruct array operations
+            func liftArrayPattern(indices: [Int], outputs: [String], hasRestElement: Bool) -> String {
+                assert(indices.count == outputs.count)
+
+                var arrayPattern = ""
+                var lastIndex = 0
+                for (index, output) in zip(indices, outputs) {
+                    let skipped = index - lastIndex
+                    lastIndex = index
+                    let dots = index == indices.last! && hasRestElement ? "..." : ""
+                    arrayPattern += String(repeating: ",", count: skipped) + dots + output
+                }
+
+                return arrayPattern
+            }
+
             // Helper functions to lift a function definition
             func liftFunctionDefinitionParameters(_ op: BeginAnyFunctionDefinition) -> String {
                 assert(instr.op === op)
@@ -419,6 +435,14 @@ public class JavaScriptLifter: Lifter {
                 let expr = AssignmentExpression.new() <> input(0) <> " = " <> input(1)
                 w.emit(expr)
 
+            case let op as DestructArray:
+                let outputs = instr.outputs.map({ $0.identifier })
+                w.emit("\(varDecl) [\(liftArrayPattern(indices: op.indices, outputs: outputs, hasRestElement: op.hasRestElement))] = \(input(0));")
+
+            case let op as DestructArrayAndReassign:
+                let outputs = instr.inputs.dropFirst().map({ $0.identifier })
+                w.emit("[\(liftArrayPattern(indices: op.indices, outputs: outputs, hasRestElement: op.hasRestElement))] = \(input(0));")
+
             case let op as Compare:
                 output = BinaryExpression.new() <> input(0) <> " " <> op.op.token <> " " <> input(1)
 
diff --git a/Sources/Fuzzilli/Mutators/OperationMutator.swift b/Sources/Fuzzilli/Mutators/OperationMutator.swift
index f1c8923bb..c89bbca96 100644
--- a/Sources/Fuzzilli/Mutators/OperationMutator.swift
+++ b/Sources/Fuzzilli/Mutators/OperationMutator.swift
@@ -117,6 +117,24 @@ public class OperationMutator: BaseInstructionMutator {
             newOp = BinaryOperation(chooseUniform(from: allBinaryOperators))
         case is ReassignWithBinop:
             newOp = ReassignWithBinop(chooseUniform(from: allBinaryOperators))
+        case let op as DestructArray:
+            var newIndices = Set(op.indices)
+            if newIndices.count > 0 {
+                newIndices.remove(newIndices.randomElement()!)
+                while newIndices.count != op.indices.count {
+                    newIndices.insert(Int.random(in: 0..<10))
+                }
+            }
+            newOp = DestructArray(indices: newIndices.sorted(), hasRestElement: !op.hasRestElement)
+        case let op as DestructArrayAndReassign:
+            var newIndices = Set(op.indices)
+            if newIndices.count > 0 {
+                newIndices.remove(newIndices.randomElement()!)
+                while newIndices.count != op.indices.count {
+                    newIndices.insert(Int.random(in: 0..<10))
+                }
+            }
+            newOp = DestructArrayAndReassign(indices: newIndices.sorted(), hasRestElement: !op.hasRestElement)
         case is Compare:
             newOp = Compare(chooseUniform(from: allComparators))
         case is LoadFromScope:
diff --git a/Sources/Fuzzilli/Protobuf/operations.pb.swift b/Sources/Fuzzilli/Protobuf/operations.pb.swift
index 3ea2c2839..359623730 100644
--- a/Sources/Fuzzilli/Protobuf/operations.pb.swift
+++ b/Sources/Fuzzilli/Protobuf/operations.pb.swift
@@ -950,6 +950,34 @@ public struct Fuzzilli_Protobuf_Reassign {
   public init() {}
 }
 
+public struct Fuzzilli_Protobuf_DestructArray {
+  // SwiftProtobuf.Message conformance is added in an extension below. See the
+  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+  // methods supported on all messages.
+
+  public var indices: [Int32] = []
+
+  public var hasRestElement_p: Bool = false
+
+  public var unknownFields = SwiftProtobuf.UnknownStorage()
+
+  public init() {}
+}
+
+public struct Fuzzilli_Protobuf_DestructArrayAndReassign {
+  // SwiftProtobuf.Message conformance is added in an extension below. See the
+  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+  // methods supported on all messages.
+
+  public var indices: [Int32] = []
+
+  public var hasRestElement_p: Bool = false
+
+  public var unknownFields = SwiftProtobuf.UnknownStorage()
+
+  public init() {}
+}
+
 public struct Fuzzilli_Protobuf_Compare {
   // SwiftProtobuf.Message conformance is added in an extension below. See the
   // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
@@ -3046,6 +3074,82 @@ extension Fuzzilli_Protobuf_Reassign: SwiftProtobuf.Message, SwiftProtobuf._Mess
   }
 }
 
+extension Fuzzilli_Protobuf_DestructArray: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+  public static let protoMessageName: String = _protobuf_package + ".DestructArray"
+  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+    1: .same(proto: "indices"),
+    2: .same(proto: "hasRestElement"),
+  ]
+
+  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
+    while let fieldNumber = try decoder.nextFieldNumber() {
+      // The use of inline closures is to circumvent an issue where the compiler
+      // allocates stack space for every case branch when no optimizations are
+      // enabled. https://github.com/apple/swift-protobuf/issues/1034
+      switch fieldNumber {
+      case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.indices) }()
+      case 2: try { try decoder.decodeSingularBoolField(value: &self.hasRestElement_p) }()
+      default: break
+      }
+    }
+  }
+
+  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
+    if !self.indices.isEmpty {
+      try visitor.visitPackedInt32Field(value: self.indices, fieldNumber: 1)
+    }
+    if self.hasRestElement_p != false {
+      try visitor.visitSingularBoolField(value: self.hasRestElement_p, fieldNumber: 2)
+    }
+    try unknownFields.traverse(visitor: &visitor)
+  }
+
+  public static func ==(lhs: Fuzzilli_Protobuf_DestructArray, rhs: Fuzzilli_Protobuf_DestructArray) -> Bool {
+    if lhs.indices != rhs.indices {return false}
+    if lhs.hasRestElement_p != rhs.hasRestElement_p {return false}
+    if lhs.unknownFields != rhs.unknownFields {return false}
+    return true
+  }
+}
+
+extension Fuzzilli_Protobuf_DestructArrayAndReassign: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+  public static let protoMessageName: String = _protobuf_package + ".DestructArrayAndReassign"
+  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+    1: .same(proto: "indices"),
+    2: .same(proto: "hasRestElement"),
+  ]
+
+  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
+    while let fieldNumber = try decoder.nextFieldNumber() {
+      // The use of inline closures is to circumvent an issue where the compiler
+      // allocates stack space for every case branch when no optimizations are
+      // enabled. https://github.com/apple/swift-protobuf/issues/1034
+      switch fieldNumber {
+      case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.indices) }()
+      case 2: try { try decoder.decodeSingularBoolField(value: &self.hasRestElement_p) }()
+      default: break
+      }
+    }
+  }
+
+  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
+    if !self.indices.isEmpty {
+      try visitor.visitPackedInt32Field(value: self.indices, fieldNumber: 1)
+    }
+    if self.hasRestElement_p != false {
+      try visitor.visitSingularBoolField(value: self.hasRestElement_p, fieldNumber: 2)
+    }
+    try unknownFields.traverse(visitor: &visitor)
+  }
+
+  public static func ==(lhs: Fuzzilli_Protobuf_DestructArrayAndReassign, rhs: Fuzzilli_Protobuf_DestructArrayAndReassign) -> Bool {
+    if lhs.indices != rhs.indices {return false}
+    if lhs.hasRestElement_p != rhs.hasRestElement_p {return false}
+    if lhs.unknownFields != rhs.unknownFields {return false}
+    return true
+  }
+}
+
 extension Fuzzilli_Protobuf_Compare: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
   public static let protoMessageName: String = _protobuf_package + ".Compare"
   public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
diff --git a/Sources/Fuzzilli/Protobuf/operations.proto b/Sources/Fuzzilli/Protobuf/operations.proto
index bac259548..9d18e187b 100644
--- a/Sources/Fuzzilli/Protobuf/operations.proto
+++ b/Sources/Fuzzilli/Protobuf/operations.proto
@@ -256,6 +256,16 @@ message Dup {
 message Reassign {
 }
 
+message DestructArray {
+    repeated int32 indices = 1;
+    bool hasRestElement = 2;
+}
+
+message DestructArrayAndReassign {
+    repeated int32 indices = 1;
+    bool hasRestElement = 2;
+}
+
 enum Comparator {
     EQUAL = 0;
     STRICT_EQUAL = 1;
diff --git a/Sources/Fuzzilli/Protobuf/program.pb.swift b/Sources/Fuzzilli/Protobuf/program.pb.swift
index 57d12ce45..e75ab6b50 100644
--- a/Sources/Fuzzilli/Protobuf/program.pb.swift
+++ b/Sources/Fuzzilli/Protobuf/program.pb.swift
@@ -593,6 +593,22 @@ public struct Fuzzilli_Protobuf_Instruction {
     set {operation = .reassign(newValue)}
   }
 
+  public var destructArray: Fuzzilli_Protobuf_DestructArray {
+    get {
+      if case .destructArray(let v)? = operation {return v}
+      return Fuzzilli_Protobuf_DestructArray()
+    }
+    set {operation = .destructArray(newValue)}
+  }
+
+  public var destructArrayAndReassign: Fuzzilli_Protobuf_DestructArrayAndReassign {
+    get {
+      if case .destructArrayAndReassign(let v)? = operation {return v}
+      return Fuzzilli_Protobuf_DestructArrayAndReassign()
+    }
+    set {operation = .destructArrayAndReassign(newValue)}
+  }
+
   public var compare: Fuzzilli_Protobuf_Compare {
     get {
       if case .compare(let v)? = operation {return v}
@@ -998,6 +1014,8 @@ public struct Fuzzilli_Protobuf_Instruction {
     case reassignWithBinop(Fuzzilli_Protobuf_ReassignWithBinop)
     case dup(Fuzzilli_Protobuf_Dup)
     case reassign(Fuzzilli_Protobuf_Reassign)
+    case destructArray(Fuzzilli_Protobuf_DestructArray)
+    case destructArrayAndReassign(Fuzzilli_Protobuf_DestructArrayAndReassign)
     case compare(Fuzzilli_Protobuf_Compare)
     case conditionalOperation(Fuzzilli_Protobuf_ConditionalOperation)
     case eval(Fuzzilli_Protobuf_Eval)
@@ -1276,6 +1294,14 @@ public struct Fuzzilli_Protobuf_Instruction {
         guard case .reassign(let l) = lhs, case .reassign(let r) = rhs else { preconditionFailure() }
         return l == r
       }()
+      case (.destructArray, .destructArray): return {
+        guard case .destructArray(let l) = lhs, case .destructArray(let r) = rhs else { preconditionFailure() }
+        return l == r
+      }()
+      case (.destructArrayAndReassign, .destructArrayAndReassign): return {
+        guard case .destructArrayAndReassign(let l) = lhs, case .destructArrayAndReassign(let r) = rhs else { preconditionFailure() }
+        return l == r
+      }()
       case (.compare, .compare): return {
         guard case .compare(let l) = lhs, case .compare(let r) = rhs else { preconditionFailure() }
         return l == r
@@ -1619,6 +1645,8 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
     95: .same(proto: "reassignWithBinop"),
     37: .same(proto: "dup"),
     38: .same(proto: "reassign"),
+    116: .same(proto: "destructArray"),
+    117: .same(proto: "destructArrayAndReassign"),
     39: .same(proto: "compare"),
     96: .same(proto: "conditionalOperation"),
     40: .same(proto: "eval"),
@@ -2966,6 +2994,32 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
           self.operation = .storeSuperPropertyWithBinop(v)
         }
       }()
+      case 116: try {
+        var v: Fuzzilli_Protobuf_DestructArray?
+        var hadOneofValue = false
+        if let current = self.operation {
+          hadOneofValue = true
+          if case .destructArray(let m) = current {v = m}
+        }
+        try decoder.decodeSingularMessageField(value: &v)
+        if let v = v {
+          if hadOneofValue {try decoder.handleConflictingOneOf()}
+          self.operation = .destructArray(v)
+        }
+      }()
+      case 117: try {
+        var v: Fuzzilli_Protobuf_DestructArrayAndReassign?
+        var hadOneofValue = false
+        if let current = self.operation {
+          hadOneofValue = true
+          if case .destructArrayAndReassign(let m) = current {v = m}
+        }
+        try decoder.decodeSingularMessageField(value: &v)
+        if let v = v {
+          if hadOneofValue {try decoder.handleConflictingOneOf()}
+          self.operation = .destructArrayAndReassign(v)
+        }
+      }()
       default: break
       }
     }
@@ -3380,6 +3434,14 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
       guard case .storeSuperPropertyWithBinop(let v)? = self.operation else { preconditionFailure() }
       try visitor.visitSingularMessageField(value: v, fieldNumber: 115)
     }()
+    case .destructArray?: try {
+      guard case .destructArray(let v)? = self.operation else { preconditionFailure() }
+      try visitor.visitSingularMessageField(value: v, fieldNumber: 116)
+    }()
+    case .destructArrayAndReassign?: try {
+      guard case .destructArrayAndReassign(let v)? = self.operation else { preconditionFailure() }
+      try visitor.visitSingularMessageField(value: v, fieldNumber: 117)
+    }()
     case nil: break
     }
     try unknownFields.traverse(visitor: &visitor)
diff --git a/Sources/Fuzzilli/Protobuf/program.proto b/Sources/Fuzzilli/Protobuf/program.proto
index 044ec5d76..2fc52e69d 100644
--- a/Sources/Fuzzilli/Protobuf/program.proto
+++ b/Sources/Fuzzilli/Protobuf/program.proto
@@ -82,6 +82,8 @@ message Instruction {
         ReassignWithBinop reassignWithBinop = 95;
         Dup dup = 37;
         Reassign reassign = 38;
+        DestructArray destructArray = 116;
+        DestructArrayAndReassign destructArrayAndReassign = 117;
         Compare compare = 39;
         ConditionalOperation conditionalOperation = 96;
         Eval eval = 40;
diff --git a/Sources/FuzzilliCli/CodeGeneratorWeights.swift b/Sources/FuzzilliCli/CodeGeneratorWeights.swift
index d5b2bf166..65dd03f07 100644
--- a/Sources/FuzzilliCli/CodeGeneratorWeights.swift
+++ b/Sources/FuzzilliCli/CodeGeneratorWeights.swift
@@ -70,6 +70,8 @@ let codeGeneratorWeights = [
     "ReassignWithBinopGenerator":               25,
     "DupGenerator":                             2,
     "ReassignmentGenerator":                    25,
+    "DestructArrayGenerator":                   7,
+    "DestructArrayAndReassignGenerator":        7,
     "WithStatementGenerator":                   5,
     "LoadFromScopeGenerator":                   4,
     "StoreToScopeGenerator":                    4,
diff --git a/Tests/FuzzilliTests/LifterTest.swift b/Tests/FuzzilliTests/LifterTest.swift
index 94a2ccd30..f4ec79d3d 100644
--- a/Tests/FuzzilliTests/LifterTest.swift
+++ b/Tests/FuzzilliTests/LifterTest.swift
@@ -38,7 +38,7 @@ class LifterTests: XCTestCase {
         let b = fuzzer.makeBuilder()
         let lifter = FuzzILLifter()
 
-        for _ in 0..<10 {
+        for _ in 0..<100 {
             b.generate(n: 100)
             let program = b.finalize()
 
@@ -1034,6 +1034,63 @@ class LifterTests: XCTestCase {
 
         XCTAssertEqual(lifted_program,expected_program)
     }
+
+    func testArrayDestructLifting() {
+        let fuzzer = makeMockFuzzer()
+        let b = fuzzer.makeBuilder()
+
+        var initialValues = [Variable]()
+        initialValues.append(b.loadInt(15))
+        initialValues.append(b.loadInt(30))
+        initialValues.append(b.loadString("Hello"))
+        initialValues.append(b.loadString("World"))
+        let v4 = b.createArray(with: initialValues)
+
+        b.destruct(v4, selecting: [0,1])
+        b.destruct(v4, selecting: [0,2,5])
+
+        b.destruct(v4, selecting: [0,2], hasRestElement: true)
+
+        let program = b.finalize()
+        let lifted_program = fuzzer.lifter.lift(program)
+        let expected_program = """
+        const v4 = [15,30,"Hello","World"];
+        let [v5,v6] = v4;
+        let [v7,,v8,,,v9] = v4;
+        let [v10,,...v11] = v4;
+
+        """
+
+        XCTAssertEqual(lifted_program,expected_program)
+    }
+
+    func testArrayDestructAndReassignLifting() {
+        let fuzzer = makeMockFuzzer()
+        let b = fuzzer.makeBuilder()
+
+        var initialValues = [Variable]()
+        initialValues.append(b.loadInt(15))
+        initialValues.append(b.loadInt(30))
+        initialValues.append(b.loadString("Hello"))
+        initialValues.append(b.loadString("World"))
+        let v4 = b.createArray(with: initialValues)
+        let v8 = b.loadInt(1000)
+        let v9 = b.loadBuiltin("JSON")
+
+        b.destruct(v4, selecting: [0,2], into: [v8, v9], hasRestElement: true)
+
+        let program = b.finalize()
+        let lifted_program = fuzzer.lifter.lift(program)
+        let expected_program = """
+        const v4 = [15,30,"Hello","World"];
+        let v5 = 1000;
+        let v6 = JSON;
+        [v5,,...v6] = v4;
+
+        """
+
+        XCTAssertEqual(lifted_program,expected_program)
+    }
 }
 
 extension LifterTests {
@@ -1065,7 +1122,9 @@ extension LifterTests {
             ("testConstructWithSpreadLifting", testConstructWithSpreadLifting),
             ("testCallWithSpreadLifting", testCallWithSpreadLifting),
             ("testPropertyAndElementWithBinopLifting", testPropertyAndElementWithBinopLifting),
-            ("testSuperPropertyWithBinopLifting", testSuperPropertyWithBinopLifting)
+            ("testSuperPropertyWithBinopLifting", testSuperPropertyWithBinopLifting),
+            ("testArrayDestructLifting",testArrayDestructLifting),
+            ("testArrayDestructAndReassignLifting", testArrayDestructAndReassignLifting),
         ]
     }
 }
