Skip to content

Instantly share code, notes, and snippets.

@olleharstedt
Created September 25, 2023 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olleharstedt/228f6e4a5ccf3ee97b7ab3f83362873c to your computer and use it in GitHub Desktop.
Save olleharstedt/228f6e4a5ccf3ee97b7ab3f83362873c to your computer and use it in GitHub Desktop.
Memory polymorph and polyglot SplDoublyLinkedList
//<?php echo "\x08\x08"; ob_start(); ?>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <glib.h>
#include <math.h>
#include <phollylib.c>
#if __PHP__//<?php
class GString { public $str; public function __construct($str) { $this->str = $str; } }
function g_string_new(string $str) { return new GString($str); }
function g_string_append(GString $s1, string $s2) { return new GString($s1->str . $s2); }
define("int", "int");
define("float", "float");
define("string", "string");
define("SplDoublyLinkedList", "SplDoublyLinkedList");
function array_get($type, $arr, $i) { return $arr[$i]; }
function array_make($type, $length, ...$values) { return $values; }
function pprintf($format, ...$args) { fwrite( STDOUT, sprintf( $format, ...$args)); }
#endif//?>
//<?php
#__C__ typedef struct Point* Point;
class Point {
#define public int
#define __prop_x $__prop_x
public $__prop_x;
#undef public
#define public int
#define __prop_y $__prop_y
public $__prop_y;
#undef public
#__C__ struct mem mem;
// End of C struct def. Class methods are outside the struct.
#__C__ };
#if __PHP__
// End of PHP class def.
};
#endif
#if __PHP__
define("Point", "Point");
#endif
//?>
// Function pointer init
Point Point__constructor(Point $p, struct mem m)
{
$p->mem = m;
return $p;
}
//<?php
#define function void
function printlist(SplDoublyLinkedList $list)
#undef function
{
$list->rewind(
#__C__ $list
);
do {
#__C__ Point
$item = $list->current(
#__C__ $list
);
printf("Point x = %ld\n", $item->__prop_x);
$list->next(
#__C__ $list
);
} while ($list->valid(
#__C__ $list
));
}
#define function void
function additems(SplDoublyLinkedList $list, int $nr)
#undef function
{
#__C__ int
$a = 0;
do {
#__C__ Point
$p = new(Point
#__C__, $list->mem
);
$p->__prop_x = $a;
$p->__prop_y = $a;
$list->push(
#__C__ $list,
$p);
$a++;
} while ($a < $nr);
}
#define function int
function main()
#undef function
{
#__C__ GC_INIT();
#__C__ Arena __a = malloc(sizeof(struct Arena));
#__C__ arena_init(__a, malloc(256), 256);
#__C__ arena_mem.alloc = &arena_alloc;
#__C__ arena_mem.arena = __a;
#__C__ SplDoublyLinkedList
$list1 = new(SplDoublyLinkedList
#__C__, arena_mem
);
additems($list1, 10);
printlist($list1);
#__C__ SplDoublyLinkedList
$list2 = new(SplDoublyLinkedList
#__C__, gc_mem
);
additems($list2, 10);
printlist($list2);
return 0;
}
// ?>
// <?php ob_end_clean(); main();
@olleharstedt
Copy link
Author

Compiles with

cat tmp.c | sed -e "s/#__C__//g" | gcc -xc - -lgc -I. -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/

assuming you have phollylib.c in working folder.

Also runs with php.

@olleharstedt
Copy link
Author

Original PHP code:

<?php // @pholyglot

class Point
{
    public int $x;
    public int $y;
}

/**
 * @param SplDoublyLinkedList<Point> $list
 */
function printlist(SplDoublyLinkedList $list): void
{
    foreach ($list as $item) {
        printf("Point x = %d\n", $item->x);
    }
}

/**
 * @param SplDoublyLinkedList<Point> $list
 */
function additems(SplDoublyLinkedList $list, int $nr): void
{
    $a = 0;
    do {
        // Use same memory allocation as $list
        $p = /** @alloc $list */ new Point();
        $p->x = $a;
        $p->y = $a;
        $list->push($p);
        $a++;
    } while ($a < $nr);
}

function main(): int
{
    /** @var SplDoublyLinkedList<Point> */
    $list1 = /** @alloc arena */ new SplDoublyLinkedList();
    additems($list1, 10);
    printlist($list1);

    // Defaults to Boehm GC
    /** @var SplDoublyLinkedList<Point> */
    $list2 = /** @alloc boehm */ new SplDoublyLinkedList();
    additems($list2, 10);
    printlist($list2);

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment