Bug 138155 - "CallByName" does not work when the returned value is an array
Summary: "CallByName" does not work when the returned value is an array
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
4.0.0.3 release
Hardware: All All
: medium normal
Assignee: Not Assigned
URL: https://docs.microsoft.com/en-us/open...
Whiteboard:
Keywords:
Depends on:
Blocks: Macro-StarBasic
  Show dependency treegraph
 
Reported: 2020-11-12 09:57 UTC by Jean-Pierre Ledure
Modified: 2024-01-27 19:05 UTC (History)
8 users (show)

See Also:
Crash report or crash signature:


Attachments
Test case (19.11 KB, application/vnd.oasis.opendocument.text)
2020-11-12 10:05 UTC, Jean-Pierre Ledure
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-Pierre Ledure 2020-11-12 09:57:01 UTC
Description:
The CallByName builtin function allows for the dynamic execution of a method given by its name.
The arguments of CallByName are:
1. The Basic object on which to apply the method
2. The name of the method as a string
3. The call type (1 for a usual method)
4+. The effective arguments of the method

When one of the arguments (4+) is an array, then next error is raised:
BASIC runtime error. Incorrect property value.

The same error is raised when the value returned by the called method is itself an array.

For any other variable type, including a Basic  object, a user-defined type, etc, CallByName works fine.

Steps to Reproduce:
1. In the Basic IDE, store next code in module Module1 of any (may be empty) LO document:
Option Explicit
Option Compatible
Sub TestCallByNameArray()
Dim a,b,c,d,e,f,g
Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
	Set a = Module2
	b = Array(1,2,3)	
	c = CallByName(a, "SomeMethod", vbMethod, b)
End Sub

2. Store next code in Module2 of the same document:
Function SomeMethod(arr as Variant) As Variant
	SomeMethod = arr
End Function

3. Run the TestCallByNameArray() Sub


Actual Results:
"BASIC runtime error. Incorrect property value." on the line:
c = CallByName(a, "SomeMethod", vbMethod, b)


Expected Results:
The variable "c" should contain the output of the called function, i.e. Ayyar(1,2,3).


Reproducible: Always


User Profile Reset: No



Additional Info:
Version: 7.0.2.2
Build ID: 8349ace3c3162073abd90d81fd06dcfb6b36b994
CPU threads: 6; OS: Linux 5.4; UI render: default; VCL: kf5
Locale: en-US (en_US.UTF-8); UI: en-US
Calc: threaded
Comment 1 Jean-Pierre Ledure 2020-11-12 10:05:24 UTC
Created attachment 167231 [details]
Test case

To reproduce the error:

- open the attached file
- In the Basic IDE, run the TestCallByNameArray() Sub stored in Module1.
Comment 3 Andreas Heinisch 2020-12-01 17:59:44 UTC
Confirmed in Version 4.0.0.3 (Build ID: 527dba6f6e0cfbbc71bd6e7b88a52699bb48799)
Comment 4 Arnaud Versini 2020-12-27 11:25:02 UTC
The issue is only with return value, no problem for parameters
Comment 5 Jean-Pierre Ledure 2021-07-14 09:47:51 UTC
Added Mike Kaganski to cc-list.

Mike,
if you ever can help solving this issue, this would improve the mechanism used by ScriptForge for Python calls handling, that is based on CallBtName().

Thanks anyway for your support.
Comment 6 Mike Kaganski 2022-07-14 06:40:47 UTC
The problem happens in SbRtl_CallByName [1], in SbMethod::Call [2], when calling SbxValue::Put [3]. The latter one checks if rVal.eType & 0xF000 gives non-zero, and errors out in that case. When the assigned value is an array, rVal.eType has SbxDataType::SbxARRAY flag (0x2000) [4].

Returning arrays from functions works, so we need to check how the return is implemented, and use that instead of SbxValue::Put. Andreas: the one for you? ;)

[1] https://opengrok.libreoffice.org/xref/core/basic/source/runtime/methods1.cxx?r=bc1ab88f&mo=2931&fi=96#205
[2] https://opengrok.libreoffice.org/xref/core/basic/source/classes/sbxmod.cxx?r=f4ff0ed5#2071
[3] https://opengrok.libreoffice.org/xref/core/basic/source/sbx/sbxvalue.cxx?r=565a5fde#392
[4] https://opengrok.libreoffice.org/xref/core/include/basic/sbxdef.hxx?r=de81c254&mo=3494&fi=80#80
Comment 7 Andreas Heinisch 2022-07-14 07:17:09 UTC
I tried to tackle this bug several times :) maybe this time we can get over it. It actual fails in SbxValue::TheRealValue [1] because the return value is an object and not an array. I have to check the differences between returning an array directly and using call by name.

[1] https://opengrok.libreoffice.org/xref/core/basic/source/sbx/sbxvalue.cxx?r=565a5fde#201
Comment 8 Mike Kaganski 2022-07-14 07:35:17 UTC
(In reply to Mike Kaganski from comment #6)

Oh sorry, I need to stop answering after only code-reading, without debugging.

I must say that for me, the problem manifests a bit different, not with "BASIC runtime error. Incorrect property value.", but with "BASIC runtime error. '9' Index out of defined range."

Then, debugging that, the call stack at the moment of generating *that* error is

> sblo.dll!SbxDimArray::Offset(SbxArray * pPar) Line 504	C++
> sblo.dll!SbxDimArray::Get(SbxArray * pPar) Line 532	C++
> sblo.dll!SbiRuntime::CheckArray(SbxVariable * pElem) Line 3965	C++
> sblo.dll!SbiRuntime::FindElement(SbxObject * pObj, unsigned long nOp1, unsigned long nOp2, ErrCode nNotFound, bool bLocal, bool bStatic) Line 3737	C++
> sblo.dll!SbiRuntime::StepRTL(unsigned long nOp1, unsigned long nOp2) Line 4132	C++
> sblo.dll!SbiRuntime::Step() Line 832	C++
> sblo.dll!`anonymous namespace'::RunInitGuard::run() Line 1015	C++
> sblo.dll!SbModule::Run(SbMethod * pMeth) Line 1178	C++
> sblo.dll!SbModule::Notify(SfxBroadcaster & rBC, const SfxHint & rHint) Line 776	C++
> svllo.dll!SfxBroadcaster::Broadcast(const SfxHint & rHint) Line 41	C++
> sblo.dll!SbMethod::Broadcast(SfxHintId nHintId) Line 2113	C++
> sblo.dll!SbxValue::Get(SbxValues & rRes) Line 289	C++
> basctllo.dll!basctl::RunMethod(const SbMethod * pMethod) Line 281	C++
> basctllo.dll!basctl::ModulWindow::BasicExecute() Line 367	C++
> basctllo.dll!basctl::ModulWindow::BasicRun() Line 387	C++
> basctllo.dll!basctl::ModulWindow::ExecuteCommand(SfxRequest & rReq) Line 908	C++
> basctllo.dll!basctl::Shell::ExecuteBasic(SfxRequest & rReq) Line 235	C++
> basctllo.dll!SfxStubbasctl_ShellExecuteBasic(SfxShell * pShell, SfxRequest & rReq) Line 153	C++
> ...

and I am really confused with what is the logic of SbiRuntime::CheckArray [1] - it tries to get the element defined by parameter array in the returned array, which looks absolutely crazy to me. pElem points to "CallByName" method, pElemObj (and pDimArray) points to the returned array(1,2,3), and pPar points to the 5-element array of [ptr_to_CallByName_as_retval, ptr_to_Module2, "SomeMethod", 1, array(1,2,3)]. SbxDimArray::Offset takes the passed 5-element array as the array of indices in the dimensions (1 in pDimArray), and indeed, that fails.

OTOH, maybe there's something missing like clearing of the parameters before returning from SbRtl_CallByName ... but IIUC, that should not happen there, needs debugging. Actually, I'm a bit lost. ATM, I can't spend much time on this, sorry.

[1] https://opengrok.libreoffice.org/xref/core/basic/source/runtime/runtime.cxx?r=7c9d99a5#3952
Comment 9 Mike Kaganski 2022-07-14 07:38:46 UTC
(In reply to Mike Kaganski from comment #8)

Ouch, I need some morning coffee. Sorry for spamming.

The mentioned "BASIC runtime error. '9' Index out of defined range." is in VBASupport mode, not in Compatible mode, as described in comment 0. Sorry again.
Comment 10 fkoch 2023-11-21 06:57:45 UTC Comment hidden (spam)