Created
September 25, 2023 19:54
-
-
Save olleharstedt/228f6e4a5ccf3ee97b7ab3f83362873c to your computer and use it in GitHub Desktop.
Memory polymorph and polyglot SplDoublyLinkedList
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//<?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(); |
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
Compiles with
assuming you have phollylib.c in working folder.
Also runs with php.