Hatena::Groupphpext

讃容日記<拡張版>

2008-03-04

CodeGen_PECLのグローバル変数コンストラクタ&デストラクタを修正してみた

14:09

svnでもそのままなので、あとでちゃんとバグレポートする。

diff -ur CodeGen_PECL-1.1.0.orig/PECL/Element/Global.php CodeGen_PECL-1.1.0/PECL/Element/Global.php
--- CodeGen_PECL-1.1.0.orig/PECL/Element/Global.php
+++ CodeGen_PECL-1.1.0/PECL/Element/Global.php
@@ -184,7 +184,13 @@
      */
     static function cCodeHeader($name) 
     { 
-        return "static void php_{$name}_init_globals(zend_{$name}_globals *{$name}_globals)\n{\n";
+        return '#if ZEND_EXTENSION_API_NO < 220060519
+#define PHP_GINIT_FUNCTION(name) void php_##name##_init_globals(zend_##name##_globals *name##_globals TSRMLS_DC)
+#endif
+
+static PHP_GINIT_FUNCTION('.$name.')
+{
+';
     }
 
     /**
@@ -229,7 +235,11 @@
         return '
 }
 
-static void php_'.$name.'_shutdown_globals(zend_'.$name.'_globals *'.$name.'_globals)
+#if ZEND_EXTENSION_API_NO < 220060519
+#define PHP_GSHUTDOWN_FUNCTION(name) void php_##name##_shutdown_globals(zend_##name##_globals *name##_globals TSRMLS_DC)
+#endif
+
+static PHP_GSHUTDOWN_FUNCTION('.$name.')
 {
 }';
     }
diff -ur CodeGen_PECL-1.1.0.orig/PECL/Extension.php CodeGen_PECL-1.1.0/PECL/Extension.php
--- CodeGen_PECL-1.1.0.orig/PECL/Extension.php
+++ CodeGen_PECL-1.1.0/PECL/Extension.php
@@ -970,7 +970,24 @@
     PHP_RSHUTDOWN($name), /* Replace with NULL if there is nothing to do at request end   */
     PHP_MINFO($name),
     \"".$this->release->getVersion()."\", 
+";
+
+        if (count($this->globals)) {
+            $code .=
+"#if ZEND_EXTENSION_API_NO >= 220060519
+    PHP_MODULE_GLOBALS({$name}),
+    PHP_GINIT({$name}),
+    PHP_GSHUTDOWN({$name}),
+    NULL,
+    STANDARD_MODULE_PROPERTIES_EX
+#else
     STANDARD_MODULE_PROPERTIES
+#endif";
+        } else {
+            $code .= "STANDARD_MODULE_PROPERTIES";
+        }
+
+        $code .= "
 };
 /* }}} */
 
@@ -1365,7 +1382,9 @@
 ";
 
         if (count($this->globals)) {
+            $code      .= "#if ZEND_EXTENSION_API_NO < 220060519\n";
             $code      .= "    ZEND_INIT_MODULE_GLOBALS({$this->name}, php_{$this->name}_init_globals, php_{$this->name}_shutdown_globals)\n";
+            $code      .= "#endif\n";
             $need_block = true;
         }
 
@@ -1437,7 +1456,12 @@
             $need_block = true;
         }
 
-        // TODO: need to destruct globals here if in ZTS mode!!111
+        if (count($this->globals)) {
+            $code      .= "#if ZEND_EXTENSION_API_NO < 220060519 && !defined(ZTS)\n";
+            $code      .= "    php_{$this->name}_shutdown_globals(&{$this->name}_globals TSRMLS_CC);\n";
+            $code      .= "#endif\n";
+            $need_block = true;
+        }
 
         if (count($this->logos)) {
             foreach ($this->logos as $logo) {
@@ -1623,10 +1647,10 @@
 
         echo $this->generateFunctionRegistrations();
             
-        echo $this->generateExtensionEntry();
- 
         echo $this->generateGlobalsC();
 
+        echo $this->generateExtensionEntry();
+
         echo $this->internalFunctionsC();
  
         echo $this->publicFunctionsC();

CarlCarl2012/11/12 11:47Furrealz? That's marvleously good to know.

ohrnfcciohrnfcci2012/11/12 23:03hYTXrx <a href="http://jcwpibihpaxg.com/">jcwpibihpaxg</a>

ksxksaksxksa2012/11/14 12:52NTPcDu , [url=http://rhnssvfaglvf.com/]rhnssvfaglvf[/url], [link=http://mwvuvczmcozv.com/]mwvuvczmcozv[/link], http://ldhqguixcqlf.com/

ryzhiptnxryzhiptnx2012/11/15 13:49FQbfKP , [url=http://mgyuyqqxbylp.com/]mgyuyqqxbylp[/url], [link=http://dwftqgcmdtvh.com/]dwftqgcmdtvh[/link], http://dsqauvwvtega.com/

2008-02-26

PHPと拡張モジュールの関係 (Mac OS X の場合)

08:59

この図は必ずしも実際の関係を正確に表しているわけではありません。

PHPと拡張モジュールの関係略式図 (Mac OS X の場合)
PHPと拡張モジュールの関係略式図 (Mac OS X の場合) posted by (C)rsk

CLI/CGI版のPHPMach-O実行可能 (MH_EXECUTE) 形式、Apacheモジュール版SAPIや外部拡張モジュールMach-Oバンドル (MH_BUNDLE) 形式、Embed SAPIはMach-O共有ライブラリ (MH_DYLIB) 形式にコンパイルされる。

Mach-Oバンドルは自分自身をロードした側のAPIを利用できるが、ロードした側はバンドルAPIを利用できない。親がブリッジを提供しない限りは、同じ親にロードされたバンドル同士でお互いのAPIを利用することもできない。ZTSモードにおけるスレッドローカルストレージtsrm_lsは、本来の役割とは別に、モジュールグローバル変数用のブリッジと見なすことができる。

また、バンドルからさらに別のバンドルをロードすることも可能であるが、直接の親のAPIしか利用できず、例えば「Apache2→mod_php5→extension」とロードされた場合、拡張モジュールからApacheAPIを利用するといったことはできない。

拡張モジュールはどのようにロードされるかというと、Zend extensionの場合はzend_extension構造体のシンボル名を決め打ちで、extensionの場合はzend_module_entry構造体のポインタを返す関数名を決め打ちで作成するようになっており、Zend Engineではphp.ini等で指定されたファイルを読み込み、そのシンボルをぶっこ抜いて登録するようになっている。

Zend extensionとextensionの違いは、大雑把に言うと前者はZend Engine実行時のフック(zend_extension構造体のメンバの関数ポインタ群)を提供するもので、後者は関数やクラス、その他の雑多なAPIを提供するものと言って良いと思う。大抵のZend extensionは、その初期化関数内で同名のextensionを登録しているが、Zend Engineをハックするだけのものも作成できる。

さてここで問題になるのは、PHP関数はzend_module_entry構造体のメンバで、クラスはモジュール初期化関数内で登録されるので、組み込み・動的ロードのどちらでも同様に利用できるのだが、CレベルのAPI関数やexternしてあるグローバル変数はそうはいかない点である。

このため、Mac OS Xでは全てのモジュールをconfigureで--(enable|with)-foo=shared,...としてはいけない。gd, hash, iconv, pcre, pdo, session, spl, xml等の他のモジュールからAPIを叩かれるモジュールは静的に組み込まねばならない。もしそれらに依存する拡張モジュールを使いたいのであれば。


・・・と、ありったけの知識を総動員してみましたが、もしかすると間違っているかもしれません。

2008-01-29

CodeGen_PECLのclass_init_xxxをZTSに対応させるパッチ

07:56

id:nemoさんのzts環境で、classを定義したらはまったYO - 拡張::nemolog - PHP拡張勉強会を見て、昔そこらへんにパッチを当てたのを思い出しました。

1回しか呼ばれない関数だし、MINITに移すのもありですね。僕もファイルを分割するとき以外はそうしてます。ちなみに別にしておいてもgccでは最適化の一環でMINITにインライン展開されるようです。

diff -ur CodeGen_PECL-1.1.0.orig/PECL/Element/Class.php CodeGen_PECL-1.1.0/PECL/Element/Class.php
--- CodeGen_PECL-1.1.0.orig/PECL/Element/Class.php      2007-08-15 03:32:02.000000000 +0900
+++ CodeGen_PECL-1.1.0/PECL/Element/Class.php   2007-11-02 19:54:40.000000000 +0900
@@ -531,7 +531,7 @@
 ";
         }
 
-        echo "static void class_init_{$this->name}(void)\n{\n";
+        echo "static void class_init_{$this->name}(TSRMLS_D)\n{\n";
 
         echo "    zend_class_entry ce;\n\n";
 
@@ -544,7 +544,7 @@
         if ($this->extends) {
             echo "    {$this->name}_ce_ptr = zend_register_internal_class_ex(&ce, NULL, \"{$this->extends}\" TSRMLS_CC);\n";
         } else {
-            echo "    {$this->name}_ce_ptr = zend_register_internal_class(&ce);\n";
+            echo "    {$this->name}_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);\n";
         }
 
         if ($this->payloadType) {
@@ -615,7 +615,7 @@
     function minitCode($extension) 
     {
         return $this->ifConditionStart() 
-            . "class_init_{$this->name}();\n"
+            . "class_init_{$this->name}(TSRMLS_C);\n"
             . $this->ifConditionEnd();
     }
         

nemonemo2008/01/29 19:36わわ、ありがとうございます。ztsはあまりメジャーではないみたいで、資料少なめ?なのでうれしいです。
とはいえ、自分でも、自分でもマクロがどう動いているかちゃんと調べないとだめですね。

LiaLia2012/09/10 13:58Always the best content from these prodigious witrers.

cbipdddwtocbipdddwto2012/09/11 13:45lpo43o <a href="http://rqaabvetnuwk.com/">rqaabvetnuwk</a>

bryislbryisl2012/09/11 22:01xBnt0n , [url=http://ltzecvngrgzu.com/]ltzecvngrgzu[/url], [link=http://yzolkuruttol.com/]yzolkuruttol[/link], http://jclcirleiuts.com/

hlostgrhlostgr2012/09/13 15:3739Mbvn , [url=http://nomqmkseitxv.com/]nomqmkseitxv[/url], [link=http://snioijqhhhjn.com/]snioijqhhhjn[/link], http://zjohiqlruwru.com/

2008-01-24

お蔵入りになった図解

16:30

連載第3回用に作ったのだけど、どう見ても青マンモス本のパクリなのでgihyo.jpで使うのは自粛。


変数への代入、コピー時の内部動作。

zval-copy
zval-copy posted by (C)rsk


リファレンスの場合。

zval-ref
zval-ref posted by (C)rsk

NereaNerea2012/11/11 18:45Kudos to you! I hadn't tohguht of that!

uuahnhuuahnh2012/11/13 06:53MU9ArR , [url=http://mstclwjryihz.com/]mstclwjryihz[/url], [link=http://bybajexhuhrh.com/]bybajexhuhrh[/link], http://lrvuegejjkpi.com/

xkqrlkdmgxkqrlkdmg2012/11/15 01:386zgljp <a href="http://dprstpawefue.com/">dprstpawefue</a>

nrdglgmgsdnrdglgmgsd2012/11/15 12:58dZVKrd , [url=http://sdlihiszxmgh.com/]sdlihiszxmgh[/url], [link=http://gaxojscxkgsm.com/]gaxojscxkgsm[/link], http://pqoxryfwtaah.com/

2008-01-23

拡張モジュールのビルド&テスト用スクリプト

09:17

こんなん使ってます。

まず、共通のファイル。

_OLDPATH="$PATH"
_TOOLSPATH="/opt/local/bin"

function confirm_build {
	local working_dir
	local module_name
	local yesno
	working_dir=`pwd`
	module_name=`basename "$working_dir"`
	while true; do
		echo -n "build $module_name for $prefix ($params)? [y/n]: "
		read yesno
		case "$yesno" in
			[Yy]|[Yy][Ee][Ss])
				return 0
				;;
			[Nn]|[Nn][Oo])
				return 1
				;;
			*)
				echo "please answer with yes or no." >&2
				;;
		esac
	done
}

function confirm_test {
	while true; do
		echo -n "run tests? [y/n]: "
		read yesno
		case "$yesno" in
			[Yy]|[Yy][Ee][Ss])
				return 0
				;;
			[Nn]|[Nn][Oo])
				return 1
				;;
			*)
				echo "please answer with yes or no." >&2
				;;
		esac
	done
}

function confirm_install {
	while true; do
		echo -n "install this? [y/n]: "
		read yesno
		case "$yesno" in
			[Yy]|[Yy][Ee][Ss])
				return 0
				;;
			[Nn]|[Nn][Oo])
				return 1
				;;
			*)
				echo "please answer with yes or no." >&2
				;;
		esac
	done
}

for prefix in $prefixes; do
	export PATH="$prefix/bin:$_TOOLSPATH:$_OLDPATH"
	PHPIZE="$prefix/bin/phpize"
	PHP_CONFIG="$prefix/bin/php-config"

	test -x "$PHPIZE" -a -x "$PHP_CONFIG" || continue

	confirm_build || continue

	for mk in $(find . -mindepth 2 -name Makefile); do
		mv $mk $(dirname "$mk")/makefile.bak
	done

	if "$PHPIZE"; then
		ICU_DIR=`"$PHP_CONFIG"  --configure-options 2> /dev/null | awk -f "$HOME/develop/build/make_scripts/php/icu-dir.awk"`
		if test -z "$ICU_DIR"; then
			./configure --with-php-config="$PHP_CONFIG" $params && make
		elif test -z "$CPPFLAGS"; then
			CPPFLAGS="$ICU_DIR" ./configure --with-php-config="$PHP_CONFIG" $params && make
		else
			CPPFLAGS="$CPPFLAGS $ICU_DIR" ./configure --with-php-config="$PHP_CONFIG" $params && make
		fi

		if [ $? != 0 ]; then
			test -e Makefile && make distclean
			"$PHPIZE" --clean
			for mk in $(find . -mindepth 2 -name makefile.bak); do
				mv $mk $(dirname "$mk")/Makefile
			done
			continue
		fi

		MODULES=""

		if confirm_test; then
			EXTENSION_DIR=`"$PHP_CONFIG" --extension-dir`
			for MODPATH in `ls "$EXTENSION_DIR"/*.so`; do
				MODNAME=`basename $MODPATH`
				if [ ! -e "./modules/$MODNAME" ]; then
					cp -p "$MODPATH" ./modules
					MODULES="$MODULES ./modules/$MODNAME"
				fi
			done
			make test
			test ! -z "$MODULES" && rm $MODULES
		fi

		confirm_install && sudo make install

		make distclean
	fi

	"$PHPIZE" --clean

	for mk in $(find . -mindepth 2 -name makefile.bak); do
		mv $mk $(dirname "$mk")/Makefile
	done

	export PATH="$_OLDPATH"
done

例えばQRコードのやつの場合、こんな内容のを作って、あとはphpizeから始まる定番の作業の代わりに使います。prefixesはモノによって4.4を外したり5.1を外します。

#!/bin/bash
prefixes="/usr/local /opt/php/6.0-zts /opt/php/6.0 /opt/php/5.3-zts /opt/php/5.3 /opt/php/5.2-zts /opt/php/5.2 /opt/php/5.1 /opt/php/4.4"
params="--enable-qr --enable-qr-gd --with-qr-tiff=/opt/local"
source "$HOME/develop/build/make_scripts/php/build.common"

追記。PHP6のconfigureのオプションからICUインストール先を抽出するawkスクリプト

{
	for (i = 0; i < NF; i++) {
		if ($i ~ /^--with-icu-dir=.+/) {
			sub(/^--with-icu-dir=/, "", $i);
			printf("-I%s/include", $i);
		}
	}
}

LucaLuca2013/02/14 20:31I'm downloading it now, I maengad to get it for a320 on the Playstation Network, which I thought was pretty decent. I love open-world games too.I should also point out that you can download GTA 1 and 2 completely free from Rockstar's website, and that is applaudable. It certainly raises Rockstar above the rest in my eyes, while other companies like Capcom are releasing the same game over and over again for the transparent reason of making profit for little to no effort.

lybinitxzjylybinitxzjy2013/02/16 11:45BsAAUT <a href="http://enmfqnxvayzq.com/">enmfqnxvayzq</a>

biosenplsoubiosenplsou2013/02/18 16:03UCkIrV , [url=http://nyzxcliwrivn.com/]nyzxcliwrivn[/url], [link=http://fybcbnyfhgtw.com/]fybcbnyfhgtw[/link], http://tvqfnweqnugf.com/