這里的 AUTOLOAD
可以理解為自動加載。具體來說就是,在正常情況下,我們不能調(diào)用一個尚未定義的函數(shù)(子例程)。不過,如果在未定義函數(shù)的包中有一個名為 AUTOLOAD
的函數(shù),那么對未定義函數(shù)的調(diào)用都會路由至這個 AUTOLOAD
函數(shù),并且會為該函數(shù)提供相同的參數(shù)。因此,我們可以在 AUTOLOAD
函數(shù)里面針對未定義的函數(shù)進行特殊處理,比如實現(xiàn)未定義的函數(shù),然后調(diào)用該函數(shù),就好像這個函數(shù)一直都存在一樣。
比如,下面的示例程序會在你調(diào)用未定義函數(shù)時發(fā)出警告,而不是直接退出:
#!/usr/bin/env perl
sub AUTOLOAD {
our $AUTOLOAD;
warn "You attempt to call an undefined function: $AUTOLOAD\n";
}
&foo; # $AUTOLOAD will be set to main::foo
print "Exit normally ...\n"
運行結果如下所示:
$ ./autoload.pl
You attempt to call an undefined function: main::foo
Exit normally ...
下面是一個更加實用的例子,即我們在 AUTOLOAD
中實現(xiàn)未定義的函數(shù):
#!/usr/bin/env perl
sub AUTOLOAD {
my $name = our $AUTOLOAD;
*$AUTOLOAD = sub { print "calling function $name(@_)\n"; };
goto &$AUTOLOAD;
}
foo(30);
goo(40);
hoo(50);
運行結果如下所示:
$ ./autoload_2.pl
calling function main::foo(30)
calling function main::goo(40)
calling function main::hoo(50)
在OpenSSL
項目中的很多地方都有用到 perl
語言,它主要負責項目建構和匯編代碼的生成工作。其中,在生成加解密算法匯編優(yōu)化代碼的 perl
腳本中,有很多架構都用到了 AUTOLOAD
機制去簡化匯編指令的書寫。下面看一個 OpenSSL
中 x86
實現(xiàn)的例子,從 crypto/chacha/asm/chacha-x86_64.pl
文件中節(jié)選出如下代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-680666.html
#!/usr/bin/env perl
sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm
{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
my $arg = pop;
$arg = "\$$arg" if ($arg*1 eq $arg);
$code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
}
@x=("%eax","%ebx","%ecx","%edx",map("%r${_}d",(8..11)),
"%nox","%nox","%nox","%nox",map("%r${_}d",(12..15)));
@t=("%esi","%edi");
sub ROUND { # critical path is 24 cycles per round
my ($a0,$b0,$c0,$d0)=@_;
my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
my ($xc,$xc_)=map("\"$_\"",@t);
my @x=map("\"$_\"",@x);
(
"&add (@x[$a0],@x[$b0])", # Q1
"&xor (@x[$d0],@x[$a0])",
"&rol (@x[$d0],16)",
"&add (@x[$a1],@x[$b1])", # Q2
"&xor (@x[$d1],@x[$a1])",
"&rol (@x[$d1],16)",
"&add ($xc,@x[$d0])",
"&xor (@x[$b0],$xc)",
"&rol (@x[$b0],12)",
"&add ($xc_,@x[$d1])",
"&xor (@x[$b1],$xc_)",
"&rol (@x[$b1],12)",
)
}
foreach (&ROUND(0, 4, 8,12)) { eval; }
foreach (&ROUND(0, 5,10,15)) { eval; }
print "$code\n";
從上面的代碼可以看到,表面上,add()
,xor()
,rol()
這些函數(shù)并沒有被聲明和實現(xiàn),但該腳本定義了 AUTOLOAD
函數(shù),并在 AUTOLOAD
函數(shù)中進行了統(tǒng)一的處理,比如,將 &add(xx, yy)
函數(shù)調(diào)用轉(zhuǎn)換為了 add yy,xx
指令字符串。
因此,上述腳本的運行結果如下所示:文章來源地址http://www.zghlxwxcb.cn/news/detail-680666.html
$ ./autoload_3.pl
add %r8d,%eax
xor %eax,%r12d
rol $16,%r12d
add %r9d,%ebx
xor %ebx,%r13d
rol $16,%r13d
add %r12d,%esi
xor %esi,%r8d
rol $12,%r8d
add %r13d,%edi
xor %edi,%r9d
rol $12,%r9d
add %r9d,%eax
xor %eax,%r15d
rol $16,%r15d
add %r10d,%ebx
xor %ebx,%r12d
rol $16,%r12d
add %r15d,%esi
xor %esi,%r9d
rol $12,%r9d
add %r12d,%edi
xor %edi,%r10d
rol $12,%r10d
到了這里,關于perl 語言中 AUTOLOAD 的用法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!