Skip to content

Commit bd10a66

Browse files
committed
Start adding support for Value (broken)
:
1 parent 5a6cb7a commit bd10a66

File tree

6 files changed

+202
-15
lines changed

6 files changed

+202
-15
lines changed

.env.dist

Lines changed: 0 additions & 13 deletions
This file was deleted.

lib/JIT.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ private function compileBlockInternal(
281281
$argValue = $this->context->helper->loadValue($arg);
282282
switch ($arg->type) {
283283
case Variable::TYPE_VALUE:
284-
$ptr = $this->context->builder->call(
284+
$argValue = $this->context->builder->call(
285285
$this->context->lookupFunction('__value__readString') ,
286286
$argValue
287287

@@ -550,6 +550,40 @@ private function assignOperand(Operand $result, Variable $value): void {
550550
);
551551
$result->addref();
552552
return;
553+
} elseif ($result->type === Variable::TYPE_VALUE) {
554+
// wrap
555+
$valueRef = $result->value;
556+
$valueFrom = $value->value;
557+
switch ($value->type) {
558+
case Variable::TYPE_NULL:
559+
$this->context->builder->call(
560+
$this->context->lookupFunction('__value__writeNull') ,
561+
$valueRef
562+
563+
);
564+
565+
return;
566+
case Variable::TYPE_NATIVE_LONG:
567+
$this->context->builder->call(
568+
$this->context->lookupFunction('__value__writeLong') ,
569+
$valueRef
570+
, $valueFrom
571+
572+
);
573+
574+
return;
575+
case Variable::TYPE_NATIVE_DOUBLE:
576+
$this->context->builder->call(
577+
$this->context->lookupFunction('__value__writeDouble') ,
578+
$valueRef
579+
, $valueFrom
580+
581+
);
582+
583+
return;
584+
default:
585+
throw new \LogicException("Source type: {$value->type}");
586+
}
553587
}
554588
throw new \LogicException("Cannot assign operands of different types (yet): {$value->type}, {$result->type}");
555589
}

lib/JIT.pre

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class JIT {
272272
switch ($arg->type) {
273273
case Variable::TYPE_VALUE:
274274
compile {
275-
$ptr = __value__readString($argValue);
275+
$argValue = __value__readString($argValue);
276276
}
277277
// Fall through intentional
278278
case Variable::TYPE_STRING:
@@ -490,6 +490,29 @@ class JIT {
490490
);
491491
$result->addref();
492492
return;
493+
} elseif ($result->type === Variable::TYPE_VALUE) {
494+
// wrap
495+
$valueRef = $result->value;
496+
$valueFrom = $value->value;
497+
switch ($value->type) {
498+
case Variable::TYPE_NULL:
499+
compile {
500+
__value__writeNull($valueRef);
501+
}
502+
return;
503+
case Variable::TYPE_NATIVE_LONG:
504+
compile {
505+
__value__writeLong($valueRef, $valueFrom);
506+
}
507+
return;
508+
case Variable::TYPE_NATIVE_DOUBLE:
509+
compile {
510+
__value__writeDouble($valueRef, $valueFrom);
511+
}
512+
return;
513+
default:
514+
throw new \LogicException("Source type: {$value->type}");
515+
}
493516
}
494517
throw new \LogicException("Cannot assign operands of different types (yet): {$value->type}, {$result->type}");
495518
}

lib/JIT/Builtin/Type/Value.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ public function register(): void
143143
$fn___cfcd208495d565ef66e7dff9f98764da->addAttributeAtIndex(\PHPLLVM\Attribute::INDEX_FUNCTION, $this->context->attributes['alwaysinline']);
144144

145145
$this->context->registerFunction('__value__writeString', $fn___cfcd208495d565ef66e7dff9f98764da);
146+
147+
$fntype___cfcd208495d565ef66e7dff9f98764da = $this->context->context->functionType(
148+
$this->context->getTypeFromString('void'),
149+
false,
150+
$this->context->getTypeFromString('__value__*')
151+
152+
);
153+
$fn___cfcd208495d565ef66e7dff9f98764da = $this->context->module->addFunction('__value__writeNull', $fntype___cfcd208495d565ef66e7dff9f98764da);
154+
$fn___cfcd208495d565ef66e7dff9f98764da->addAttributeAtIndex(\PHPLLVM\Attribute::INDEX_FUNCTION, $this->context->attributes['alwaysinline']);
155+
156+
$this->context->registerFunction('__value__writeNull', $fn___cfcd208495d565ef66e7dff9f98764da);
146157
}
147158

148159
public function implement(): void
@@ -152,6 +163,7 @@ public function implement(): void
152163
$this->implementValueWriteLong();
153164
$this->implementValueReadDouble();
154165
$this->implementValueWriteDouble();
166+
$this->implementValueWriteNull();
155167
$this->implementValueDelref();
156168
}
157169

@@ -865,6 +877,116 @@ public function implementValueWriteString(): void
865877
$this->context->builder->clearInsertionPosition();
866878
}
867879

880+
public function implementValueWriteNull(): void
881+
{
882+
$fn___34173cb38f07f89ddbebc2ac9128303f = $this->context->lookupFunction('__value__writeNull');
883+
$block___34173cb38f07f89ddbebc2ac9128303f = $fn___34173cb38f07f89ddbebc2ac9128303f->appendBasicBlock('main');
884+
$this->context->builder->positionAtEnd($block___34173cb38f07f89ddbebc2ac9128303f);
885+
$value = $fn___34173cb38f07f89ddbebc2ac9128303f->getParam(0);
886+
887+
$this->context->builder->call(
888+
$this->context->lookupFunction('__value__valueDelref'),
889+
$value
890+
891+
);
892+
$__type = $this->context->getTypeFromString('int8');
893+
894+
$__kind = $__type->getKind();
895+
$__value = Variable::TYPE_NULL;
896+
switch ($__kind) {
897+
case \PHPLLVM\Type::KIND_INTEGER:
898+
if (! is_object($__value)) {
899+
$type = $__type->constInt($__value, false);
900+
901+
break;
902+
}
903+
$__other_type = $__value->typeOf();
904+
switch ($__other_type->getKind()) {
905+
case \PHPLLVM\Type::KIND_INTEGER:
906+
if ($__other_type->getWidth() >= $__type->getWidth()) {
907+
$type = $this->context->builder->truncOrBitCast($__value, $__type);
908+
} else {
909+
$type = $this->context->builder->zExtOrBitCast($__value, $__type);
910+
}
911+
912+
break;
913+
case \PHPLLVM\Type::KIND_DOUBLE:
914+
915+
$type = $this->context->builder->fpToSi($__value, $__type);
916+
917+
break;
918+
case \PHPLLVM\Type::KIND_ARRAY:
919+
case \PHPLLVM\Type::KIND_POINTER:
920+
$type = $this->context->builder->ptrToInt($__value, $__type);
921+
922+
break;
923+
default:
924+
throw new \LogicException('Unknown how to handle type pair (int, '.$__other_type->toString().')');
925+
}
926+
927+
break;
928+
case \PHPLLVM\Type::KIND_DOUBLE:
929+
if (! is_object($__value)) {
930+
$type = $__type->constReal(Variable::TYPE_NULL);
931+
932+
break;
933+
}
934+
$__other_type = $__value->typeOf();
935+
switch ($__other_type->getKind()) {
936+
case \PHPLLVM\Type::KIND_INTEGER:
937+
938+
$type = $this->context->builder->siToFp($__value, $__type);
939+
940+
break;
941+
case \PHPLLVM\Type::KIND_DOUBLE:
942+
$type = $this->context->builder->fpCast($__value, $__type);
943+
944+
break;
945+
default:
946+
throw new \LogicException('Unknown how to handle type pair (double, '.$__other_type->toString().')');
947+
}
948+
949+
break;
950+
case \PHPLLVM\Type::KIND_ARRAY:
951+
case \PHPLLVM\Type::KIND_POINTER:
952+
if (! is_object($__value)) {
953+
// this is very likely very wrong...
954+
$type = $__type->constInt($__value, false);
955+
956+
break;
957+
}
958+
$__other_type = $__value->typeOf();
959+
switch ($__other_type->getKind()) {
960+
case \PHPLLVM\Type::KIND_INTEGER:
961+
$type = $this->context->builder->intToPtr($__value, $__type);
962+
963+
break;
964+
case \PHPLLVM\Type::KIND_ARRAY:
965+
// $__tmp = $this->context->builder->($__value, $this->context->context->int64Type());
966+
// $(result) = $this->context->builder->intToPtr($__tmp, $__type);
967+
// break;
968+
case \PHPLLVM\Type::KIND_POINTER:
969+
$type = $this->context->builder->pointerCast($__value, $__type);
970+
971+
break;
972+
default:
973+
throw new \LogicException('Unknown how to handle type pair (double, '.$__other_type->toString().')');
974+
}
975+
976+
break;
977+
default:
978+
throw new \LogicException('Unsupported type cast: '.$__type->toString());
979+
}
980+
$offset = $this->context->structFieldMap[$value->typeOf()->getElementType()->getName()]['type'];
981+
$this->context->builder->store(
982+
$type,
983+
$this->context->builder->structGep($value, $offset)
984+
);
985+
$this->context->builder->returnVoid();
986+
987+
$this->context->builder->clearInsertionPosition();
988+
}
989+
868990
protected function implementValueDelref(): void
869991
{
870992
$fn___c4ca4238a0b923820dcc509a6f75849b = $this->context->lookupFunction('__value__valueDelref');

lib/JIT/Builtin/Type/Value.pre

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class Value extends Type {
3636

3737
static inline function __value__readString(__value__*): __string__*;
3838
static inline function __value__writeString(__value__*, __string__*): void;
39+
40+
static inline function __value__writeNull(__value__*): void;
3941
}
4042
}
4143

@@ -45,6 +47,7 @@ class Value extends Type {
4547
$this->implementValueWriteLong();
4648
$this->implementValueReadDouble();
4749
$this->implementValueWriteDouble();
50+
$this->implementValueWriteNull();
4851
$this->implementValueDelref();
4952
}
5053

@@ -238,4 +241,15 @@ class Value extends Type {
238241
}
239242
}
240243

244+
public function implementValueWriteNull(): void {
245+
compile {
246+
function __value__writeNull($value) {
247+
__value__valueDelref($value);
248+
$type = (int8) Variable::TYPE_NULL;
249+
$value->type = $type;
250+
return;
251+
}
252+
}
253+
}
254+
241255
}

lib/JIT/Context.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,13 @@ public function constantFetch(Operand $op): ?Variable {
448448
}
449449
// convert to PHP variable
450450
switch ($phpVar->type) {
451+
case VMVariable::TYPE_NULL:
452+
return new Variable(
453+
$this,
454+
Variable::TYPE_NULL,
455+
Variable::KIND_VALUE,
456+
$this->getTypeFromString('__value__*')->constNull()
457+
);
451458
case VMVariable::TYPE_INTEGER:
452459
$type = $this->getTypeFromString('int64');
453460
$global = $this->module->addGlobal($type, $name);

0 commit comments

Comments
 (0)