Skip to content
4 changes: 4 additions & 0 deletions src/Core/JVM/ConstantPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PHPJava\Kernel\Structures\_NameAndType;
use PHPJava\Kernel\Structures\_String;
use PHPJava\Kernel\Structures\_Utf8;
use PHPJava\Kernel\Structures\FreezableInterface;
use PHPJava\Kernel\Structures\StructureInterface;

class ConstantPool implements \ArrayAccess, \Countable, \IteratorAggregate
Expand Down Expand Up @@ -108,6 +109,9 @@ public function offsetExists($offset)
*/
public function offsetGet($offset)
{
if ($this->entries[$offset] instanceof FreezableInterface) {
$this->entries[$offset]->freeze();
}
return $this->entries[$offset];
}

Expand Down
6 changes: 0 additions & 6 deletions src/Core/JVM/Intern/InternInterface.php

This file was deleted.

41 changes: 0 additions & 41 deletions src/Core/JVM/Intern/StringIntern.php

This file was deleted.

11 changes: 0 additions & 11 deletions src/Core/JavaClassInvoker.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
namespace PHPJava\Core;

use PHPJava\Core\JVM\DynamicAccessor;
use PHPJava\Core\JVM\Intern\StringIntern;
use PHPJava\Core\JVM\StaticAccessor;
use PHPJava\Exceptions\IllegalJavaClassException;
use PHPJava\Kernel\Maps\FieldAccessFlag;
use PHPJava\Kernel\Provider\InternProvider;
use PHPJava\Kernel\Provider\ProviderInterface;
use PHPJava\Kernel\Structures\_FieldInfo;
use PHPJava\Kernel\Structures\_MethodInfo;
Expand Down Expand Up @@ -82,15 +80,6 @@ public function __construct(
}
}

// Intern provider registration.
$this->providers = [
'InternProvider' => (new InternProvider())
->add(
StringIntern::class,
new StringIntern()
),
];

$this->dynamicAccessor = new DynamicAccessor(
$this,
$this->dynamicMethods,
Expand Down
8 changes: 1 addition & 7 deletions src/Kernel/Mnemonics/_aload.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php
namespace PHPJava\Kernel\Mnemonics;

use PHPJava\Core\JVM\Intern\StringIntern;

final class _aload implements OperationInterface
{
use \PHPJava\Kernel\Core\Accumulator;
Expand All @@ -14,10 +12,6 @@ final class _aload implements OperationInterface
public function execute(): void
{
$index = $this->readByte();
$stringIntern = $this->javaClassInvoker
->getProvider('InternProvider')
->get(StringIntern::class);
$internedValue = $stringIntern[spl_object_id($this->getLocalStorage($index))] ?? null;
$this->pushToOperandStack($internedValue ?: $this->getLocalStorage($index));
$this->pushToOperandStack($this->getLocalStorage($index));
}
}
8 changes: 1 addition & 7 deletions src/Kernel/Mnemonics/_aload_0.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php
namespace PHPJava\Kernel\Mnemonics;

use PHPJava\Core\JVM\Intern\StringIntern;

final class _aload_0 implements OperationInterface
{
use \PHPJava\Kernel\Core\Accumulator;
Expand All @@ -14,10 +12,6 @@ final class _aload_0 implements OperationInterface
public function execute(): void
{
$index = 0;
$stringIntern = $this->javaClassInvoker
->getProvider('InternProvider')
->get(StringIntern::class);
$internedValue = $stringIntern[spl_object_id($this->getLocalStorage($index))] ?? null;
$this->pushToOperandStack($internedValue ?: $this->getLocalStorage($index));
$this->pushToOperandStack($this->getLocalStorage($index));
}
}
8 changes: 1 addition & 7 deletions src/Kernel/Mnemonics/_aload_1.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php
namespace PHPJava\Kernel\Mnemonics;

use PHPJava\Core\JVM\Intern\StringIntern;

final class _aload_1 implements OperationInterface
{
use \PHPJava\Kernel\Core\Accumulator;
Expand All @@ -14,10 +12,6 @@ final class _aload_1 implements OperationInterface
public function execute(): void
{
$index = 1;
$stringIntern = $this->javaClassInvoker
->getProvider('InternProvider')
->get(StringIntern::class);
$internedValue = $stringIntern[spl_object_id($this->getLocalStorage($index))] ?? null;
$this->pushToOperandStack($internedValue ?: $this->getLocalStorage($index));
$this->pushToOperandStack($this->getLocalStorage($index));
}
}
8 changes: 1 addition & 7 deletions src/Kernel/Mnemonics/_aload_2.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php
namespace PHPJava\Kernel\Mnemonics;

use PHPJava\Core\JVM\Intern\StringIntern;

final class _aload_2 implements OperationInterface
{
use \PHPJava\Kernel\Core\Accumulator;
Expand All @@ -14,10 +12,6 @@ final class _aload_2 implements OperationInterface
public function execute(): void
{
$index = 2;
$stringIntern = $this->javaClassInvoker
->getProvider('InternProvider')
->get(StringIntern::class);
$internedValue = $stringIntern[spl_object_id($this->getLocalStorage($index))] ?? null;
$this->pushToOperandStack($internedValue ?: $this->getLocalStorage($index));
$this->pushToOperandStack($this->getLocalStorage($index));
}
}
8 changes: 1 addition & 7 deletions src/Kernel/Mnemonics/_aload_3.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php
namespace PHPJava\Kernel\Mnemonics;

use PHPJava\Core\JVM\Intern\StringIntern;

final class _aload_3 implements OperationInterface
{
use \PHPJava\Kernel\Core\Accumulator;
Expand All @@ -14,10 +12,6 @@ final class _aload_3 implements OperationInterface
public function execute(): void
{
$index = 3;
$stringIntern = $this->javaClassInvoker
->getProvider('InternProvider')
->get(StringIntern::class);
$internedValue = $stringIntern[spl_object_id($this->getLocalStorage($index))] ?? null;
$this->pushToOperandStack($internedValue ?: $this->getLocalStorage($index));
$this->pushToOperandStack($this->getLocalStorage($index));
}
}
6 changes: 0 additions & 6 deletions src/Kernel/Provider/InternProvider.php

This file was deleted.

8 changes: 8 additions & 0 deletions src/Kernel/Structures/FreezableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace PHPJava\Kernel\Structures;

interface FreezableInterface
{
public function freeze(): void;
}
37 changes: 31 additions & 6 deletions src/Kernel/Structures/_Utf8.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<?php
namespace PHPJava\Kernel\Structures;

class _Utf8 implements StructureInterface
class _Utf8 implements StructureInterface, FreezableInterface
{
use \PHPJava\Kernel\Core\BinaryReader;
use \PHPJava\Kernel\Core\ConstantPool;
use \PHPJava\Kernel\Core\DebugTool;

private $length = 0;
private $string = '';
private $isWritable;
private $isFrozen = false;

/**
* @var \PHPJava\Packages\java\lang\_String $stringObject
Expand All @@ -24,23 +26,46 @@ public function execute(): void
$this->stringObject = new \PHPJava\Packages\java\lang\_String($this);
}

public function getLength()
public function getLength(): int
{
return $this->length;
}

public function getString()
public function enableWrite(bool $enable): self
{
return $this->string;
if (!$this->isFrozen) {
$this->isWritable = $enable;
}
return $this;
}

public function __toString(): string
public function freeze(): void
{
return $this->getString();
$this->isFrozen = true;
$this->enableWrite(false);
}

public function getString(): string
{
return $this->string;
}

public function getStringObject(): \PHPJava\Packages\java\lang\_String
{
return $this->stringObject;
}

public function setStringObject(\PHPJava\Packages\java\lang\_String $stringObject): self
{
if ($this->isWritable) {
$this->stringObject = $stringObject;
$this->freeze();
}
return $this;
}

public function __toString(): string
{
return $this->getString();
}
}
24 changes: 20 additions & 4 deletions src/Packages/java/lang/_String.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace PHPJava\Packages\java\lang;

use PHPJava\Core\JVM\ConstantPool;
use PHPJava\Exceptions\NotImplementedException;
use PHPJava\Kernel\Structures\_Utf8;
use PHPJava\Kernel\Types\_Char;
Expand Down Expand Up @@ -322,13 +323,28 @@ public function indexOf($a = null, $b = null)
/**
* Returns a canonical representation for the string object.
*
* @native ConstantPool
* @see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/package-summary.html#intern
* @param null|mixed $a
* @throws NotImplementedException
*/
public function intern($a = null)
{
throw new NotImplementedException(__METHOD__);
public function intern(ConstantPool $cp)
{
// Find the string from the Constant Pool.
foreach ($cp as $key => $value) {
if (!($value instanceof _Utf8)) {
continue;
}
/**
* @var _Utf8 $value
*/
if ((string) $value === (string) $this->object) {
$this->object = $value
->enableWrite(true)
->setStringObject($this);
break;
}
}
return $this;
}

/**
Expand Down
57 changes: 57 additions & 0 deletions tests/Packages/JavaLangStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,63 @@ public function testHashCode()
$this->assertSame('2728214739616339340', $values[2]);
}

public function testIntern()
{
ob_start();
$this->initiatedJavaClasses['JavaLangStringTest']
->getInvoker()
->getStatic()
->getMethods()
->call(
'intern'
);
[ $intern, $literal ] = array_filter(explode("\n", ob_get_clean()));

$this->assertIsNumeric($intern);
$this->assertIsNumeric($literal);

$this->assertSame($intern, $literal);
}

public function testNotInterned()
{
ob_start();
$this->initiatedJavaClasses['JavaLangStringTest']
->getInvoker()
->getStatic()
->getMethods()
->call(
'notInterned'
);
[ $intern, $literal ] = array_filter(explode("\n", ob_get_clean()));

$this->assertIsNumeric($intern);
$this->assertIsNumeric($literal);

$this->assertNotSame($intern, $literal);
}

public function testNotInternedAfterLiteral()
{
ob_start();
$this->initiatedJavaClasses['JavaLangStringTest']
->getInvoker()
->getStatic()
->getMethods()
->call(
'notInternedAfterLiteral'
);
[ $intern, $literal1, $literal2 ] = array_filter(explode("\n", ob_get_clean()));

$this->assertIsNumeric($intern);
$this->assertIsNumeric($literal1);
$this->assertIsNumeric($literal2);

$this->assertNotSame($intern, $literal1);
$this->assertNotSame($intern, $literal2);
$this->assertSame($literal1, $literal2);
}

public function testReplace()
{
ob_start();
Expand Down
Loading