The problem is, that having a local variable referring the same value
as the original expression 'foo' is not the same as referencing 'foo'
itself. After 'foo' is re-assigned, the local variable still refers
to the original value, not the new one.
It seems impossible to implement the reference using existing codegen
primitives, to imitate the true reference to 'foo', not to its value.
If we implement it by changing the runtime, the bytecode won't work
identically in older versions; if we introduce a new bytecode, that
would be an incompatible change.
As a workaround, only create the local With variable, when the block
variable is created using some function (as much as known by parser).
I think that there would be cases when this would still not work as
intended: an example is a property implemented using getter function;
the parser would likely treat the property as a variable, and avoid
creation of the local variable; and the getter would be called every
time a dot access will happen (which was the essence of tdf#132064).
However, this seems a better alternative to the bug fixed here.
Change-Id: I50bf679762fd2e73f215a000fa0ab60fd6ae7453
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174564
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Other "WITH" blocks create the symbol that can be found by pPool->Find,
but can be not accessible at the call site.
Change-Id: I85ecc763a1bb3fd692c2c98e674047fdbde3f8f5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173417
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
SbiRuntime::StepPUT, SbiRuntime::StepSET, SbiRuntime::StepVBASET call
checkUnoStructCopy eventually, which copies the UNO struct by value.
This is not what we need. On the other hand, SbiRuntime::StepPUTC only
makes the by-ref assignment, and makes the reference const; but Basic
code never assigns anything to the internal variable itself, only to
its members.
I hope that this time, I get it right.
Change-Id: I2b4a51a2dca9e7106e14e03360ef0d5a50b60079
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173305
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
In commit f3f46b5fe7 (tdf#132064: make
With statement only evaluate its argument once, 2024-08-17), I made
a mistake, clearing the internal variable in the end of SbiParser::With
using an Erase call, which does not just clears the variable itself,
but destroys the underlying object, which is not what we need.
I don't know how to refer to a global Nothing object to assign to the
variable; so just create an own internal Nothing, and use it in the
assignment.
Change-Id: Ic8ce52e0402d8461a9b9e4ee07614c4f0a46a95e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172006
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
This is implemented by creating a unique variable at entry of the
block, using it as the "with parent", and clearing afterwards. It
uses an invalid name, so can't be used by a user. The generation
of the bytecode is done in compatible way; only existing opcodes
were used (which was the reason to choose the implementation with
a variable), so compiled binaries in password-protected libraries
are expected to work with older versions.
The functional changes are:
1. The argument of With statement is evaluated immediately at the
start of the block; previously, it evaluated first time, when the
leading dot operator was used, and could even be never evaluated,
if the operator wasn't used. This is consistent with VBA, and has
a benefit that the lifetime of the object is guaranteed to cover
the whole block (might be useful if other block statements depend
on the object, similar to Python's 'with' statement contexts).
2. The primary goal of the change: it is only ever evaluated once,
no matter how many times was the dot operator used in the block.
Change-Id: I4dbd520538a57e3668ab706e8f45740db5d33393
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171980
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
Don't execute On expression GoSub Statement; On expression GoTo
Statement if the expression lies out of range.
Change-Id: I5c1de25918b5e812d7ec82034f8d56351374d56a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165960
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Tested-by: Jenkins
Previously, BASIC CCur used a custom, single-purpose currency string
parser which did not properly accommodate the user's locale setting.
This change replaces the custom parser with SvNumberFormatter, which
does correctly respect system locale.
Change-Id: I179915eb080e876e5e550dd350fdb86d7fa2bf4c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160848
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
cppu::UnoType<sal_uInt8> corresponds to UNO boolean, so its use made the
unsigned values be converted to a true/false in Any; and additionally,
using such a boolean Any, even having a 'true' value, as a parameter to
a double argument would make operator >>=(const Any &, double &) return
false, giving the resulting double equal to 0.
The wrong conversion of UShorts and ULongs to cppu::UnoType<sal_uInt8>
(aka TypeClass_BOOLEAN) was introduced in commit
11f9aa4fcb
Author Andreas Bregas <ab@openoffice.org>
Date Thu May 10 14:22:42 2001 +0000
#79615# sbxToUnoValue(): Choose smallest possible type for numeric values
Treating of unsigned Basic Byte as a signed cppu::UnoType<sal_Int8> (aka
TypeClass_BYTE) was already introduced in
commit c25ec0608a
Author Jens-Heiner Rechtien <hr@openoffice.org>
Date Mon Sep 18 15:18:56 2000 +0000
initial import
Then, in commit 553cf2a834
Author Andreas Bregas <ab@openoffice.org>
Date Fri Jun 08 14:59:57 2001 +0000
#87927# Map TypeClass_BYTE to SbxINTEGER instead of SbxBYTE because of signed/unsigned problem
an attempt was made to handle obviously this same problem, changing the
corresponding UNO type to TypeClass_SHORT. But it seems that it created
problems when passing arrays of Byte through UNO to COM, where it needed
to convert to a safearray, so this decision was reverted in commit
dd6ba6b64a
Author Mikhail Voytenko <mav@openoffice.org>
Date Thu Jul 08 21:33:48 2010 +0200
mib17: #162917# let basic byte use one byte, let olebridge convert sequence to safearray correctly
This change tries to avoid the problem that caused the latter revert,
by only treating Bytes as UNO shorts in getUnoTypeForSbxValue, where
scalar Byte values are considered, keeping old handling for arrays.
Change-Id: I805108743376e2fc27dd21a27c31759b76dc0d09
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136526
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Moves the custom cleanup logic to overridden SbxMethod::Clear, to simplify
the cleanup code and make sure it restores empty Variant correctly.
Change-Id: I01fa0529acd9ac787ffcda60fd6836ade4afdcb1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136108
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
...like my local ASan+UBSan build, which now happened to fail once with
> Failed: TestReplacePerformance (t = 60 s)
> Tests passed: 0
> Tests failed: 1
when the machine was under load during a parallelizing `make check`, following
up on 3564b5c6e9 "Adapt test to slow builds"
Change-Id: I8f0c8f7e6e145b6d5009f48d2af865ea5caab375
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132335
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
First, the integer function result is returned in a 64-bit register (RAX),
and truncation it to sal_Int32 breaks any pointer return value.
Second, using explicit (not vararg) first function double argument would
pass it through XMM0, without also copying it to RCX (which is guaranteed
for varargs).
Ref: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
Change-Id: I08212c44d8690d6910068b13c16af2ce899c94f2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129808
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
...like my local ASan+UBSan build, which kept failing with
> Failed: TestReplacePerformance (t = 35 s)
> Tests passed: 0
> Tests failed: 1
when the machine was under load during a parallelizing `make check`
Change-Id: I59c81a61a29df7165f6fad33e3fe3da975f05ed2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129237
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
I hope that this performance test is OK. I chose 20 s threshold, as
it works much faster on my system (under 4 s); it shouldn't be much
slower elsewhere; and both the original bug, and the regression that
followed the initial fix, made it execute orders of magnitute slower
(I expect hours on fast systems).
Change-Id: I75ee4c60e562473fe70a203faa94b48c5fbfb4fe
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129203
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
If you want to keep the string to floating point conversion semantics
in BASIC as they were in LibreOffice 6, you can either set the
LIBREOFFICE6FLOATINGPOINTMODE environment variable to some non-empty
value, or set the org.openoffice.Office.Scripting/Basic/Compatibility/
UseLibreOffice6FloatingPointConversion flag in the Expert
Configuration. (Or use a registry modification file with that effect.)
Adapt the relevant unit test accordingly. Thanks to Mike Kaganski for
showing how to access the setting in the LibreOffice registry from
Basic.
Change-Id: I13d6d5d834e1bb81ef8df489db2b1da79f01dfc5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125756
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
If a name is ending with an underscore at the end of the line, it won't
be recognized correctly and it will be wrongly interpreted as the
respective name without the underscore at the end. Instead of changing
the macro source, use a flag in order to correclty identify the line end.
Change-Id: I6f933d7382b510bffed3e2692d32c232b7084624
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123833
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Don't assign a missing optional variable to a property and don't allow
the computation/comparision including missing optional attributes.
In the previous cases a ERRCODE_BASIC_NOT_OPTIONAL is raised.
Change-Id: Iab391286fcace16c271ae511304075e2a0c5c651
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121794
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
In addtion, fixed a crash if the start position is greater than the
length of the string being searched.
Change-Id: I9bcda1131324bdfac6957018e91b3a36dd2dc3d6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118996
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>