peachpie icon indicating copy to clipboard operation
peachpie copied to clipboard

Support using value types (structs) in Peachpie

Open roberthusak opened this issue 4 years ago • 4 comments

Sample C# code:

namespace ClassLibrary
{
    public struct MyStruct
    {
        public int Value;

        public MyStruct(int value) {
            Value = value;
        }
    }
}

Sample PHP code:

function test_struct(ClassLibrary\MyStruct $typed, $untyped) {
  echo $typed->Value;
  echo $untyped->Value;
}

test_struct(new ClassLibrary\MyStruct(42), new ClassLibrary\MyStruct(43));

Thanks to boxing, echo $untyped->Value currently works, but when using a value type directly (e.g. constructing it, converting to and from it etc.), NotImplementedException is thrown.


  • [x] getting/setting properties on value types
  • [x] calling methods on value types
  • [x] constructing value types
  • [ ] calling non-readonly methods, should change the value (through boxing it in StructBox<TValue>)
    • see PhpValue.FromStruct
    • extend ConvertExpression
    • extend PhpValue.ToClr
  • [ ] write some tests

roberthusak avatar Feb 24 '21 09:02 roberthusak

I would add, that also calling methods on structs should be supported; additionally, when calling non-readonly method then the value must be copied back.

// the following might have a side effect,
// the unboxed $value should be copied back to $value or there should not be any boxing at all
$value->method();

jakubmisek avatar Feb 24 '21 18:02 jakubmisek

@roberthusak is it alright now?

jakubmisek avatar Feb 28 '21 21:02 jakubmisek

@jakubmisek Nice, the original sample works well now 👍 Certain operations still don't compile or work though, here is a more detailed use case:

C#:

namespace ClassLibrary
{
    public struct MyStruct
    {
        public int Value;

        public MyStruct(int value) {
            Value = value;
        }

        public void SetValue(int value) {
            Value = value;
        }
    }
}

PHP:

function print_structs(ClassLibrary\MyStruct $typed, $untyped) {
  echo "{$typed->Value},{$untyped->Value}\n";
}

function test_struct(ClassLibrary\MyStruct $typed, $untyped) {
  print_structs($typed, $untyped);  // 42,43

  $typed->Value = 52;
  $untyped->Value = 53;
  print_structs($typed, $untyped);  // 52,53

  $typed->SetValue(62);
  $untyped->SetValue(63);
  print_structs($typed, $untyped);  // 62,63
}

$s = new ClassLibrary\MyStruct(42);
test_struct($s, new ClassLibrary\MyStruct(43));

roberthusak avatar Mar 01 '21 23:03 roberthusak

@roberthusak that's those non-readonly methods, adding to the checklist

jakubmisek avatar Mar 02 '21 10:03 jakubmisek