`stdLambda` `stack` issue

Đã đóng
#68 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Cần làm rõ
Mức độ hoạt động
Đình trệ
Lĩnh vực
tooling

Hướng nghiên cứu

Start by reading the evaluate path for iType.oAccess and the pushV and CopyVariant entry points shown in the issue. Reproduce the object-valued stack access case from the included minimal examples, then establish a replacement approach that avoids the reported array-locking error and preserves existing stack behavior.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement lib-stdLambda

Currently in evaluate:

            Case iType.oAccess
                Select Case op.subType
                    Case ISubType.argument
                        Dim iArgIndex As Long: iArgIndex = val(mid(op.value, 2)) + LBound(vLastArgs) - 1
                        If iArgIndex <= UBound(vLastArgs) Then
                            Call pushV(stack, stackPtr, vLastArgs(iArgIndex))
                        Else
                            Call Throw("Argument " & iArgIndex & " not supplied to Lambda.")
                        End If
                    Case Else
                        Call pushV(stack, stackPtr, stack(stackPtr - op.value))

Call pushV(stack, stackPtr, stack(stackPtr - op.value)) can sometimes error when the variable at stack(stackPtr - op.value) is an object. See explanation for details. As a temporary work around we can do the following:

 '@FIX bug where if stack(stackPtr-op.value) was an object, then array will become locked. Array locking occurs by compiler to try to protect
'instances when re-allocation would move the array, and thus corrupt the pointers. By copying the variant we redivert the compiler's efforts,
'but we might actually open ourselves to errors...
Dim vAccessVar: Call CopyVariant(vAccessVar, stack(stackPtr - op.value))
Call pushV(stack, stackPtr, vAccessVar)

This may still break so we need to consider a better solution. Our suggestion is to use a Collection (i.e. linked list) instead of a dynamic array. This should have fewer issues but might sacrifice on some performance.


Explanation:

Minimal examples where error occurs:

Sub Example()
    'Initialize the array with 3 elements
    Dim myArray() As string
    ReDim myArray(0)
    Set myArray(0) = "yop"
    Call Push(myArray, myArray(0))
End Sub

Sub Push(ByRef myArray() As string, ByRef element As string)
    'Lock the array to prevent deallocation of memory for the reference parameter
    ReDim Preserve myArray(UBound(myArray) + 1)
    If IsObject(element) Then
      Set myArray(UBound(myArray)) = element
    Else
      myArray(UBound(myArray)) = element
    End If
End Sub

The issue is that element, in this case is a reference to an element within myArray... The solution to above is change element to ByVal:

Sub Push(ByRef myArray() As string, ByVal element As string)

When extended to the variant case however:

Sub Push(ByRef myArray() As variant, ByVal element As variant)

Objects are also pointers... so

Sub Example()
    'Initialize the array with 3 elements
    Dim myArray() As Variant
    ReDim myArray(0)
    Set myArray(0) = CreateObject("scripting.dictionary")
    Call Push(myArray, myArray(0))
End Sub

Sub Push(ByRef myArray() As Variant, ByVal element As Variant)
    'Lock the array to prevent deallocation of memory for the reference parameter
    ReDim Preserve myArray(UBound(myArray) + 1)
    If IsObject(element) Then
      Set myArray(UBound(myArray)) = element
    Else
      myArray(UBound(myArray)) = element
    End If
End Sub

Also errors because we have a pointer directly to myArray(0) object. So the real work around is

Sub Example()
    'Initialize the array with 3 elements
    Dim myArray() As Variant
    ReDim myArray(0)
    Set myArray(0) = CreateObject("scripting.dictionary")
    Dim v: CopyVariant(v, myArray(0))
    Call Push(myArray, v)
End Sub
Ngôn ngữ chính
VBA
Star
412
Fork
70
Merge trung bình
20 giờ 38 phút
Pull request đã merge (30 ngày)
18

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của sancarn/stdVBA

Tất cả issue của sancarn/stdVBA

Issue tương tự

Thêm issue về DevTools

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.