| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | define('INDENT', "\t"); |
|---|
| 4 | ini_set('error_reporting', E_ALL); |
|---|
| 5 | |
|---|
| 6 | function color($str, $color = 33) |
|---|
| 7 | { |
|---|
| 8 |   return "\x1B[{$color}m$str\x1B[0m"; |
|---|
| 9 | } |
|---|
| 10 | |
|---|
| 11 | function str($src, $indent = '') // {{{ |
|---|
| 12 | { |
|---|
| 13 |   if (is_array($indent)) { |
|---|
| 14 |     $indent = $indent['indent']; |
|---|
| 15 | Â Â } |
|---|
| 16 | |
|---|
| 17 | Â Â /* |
|---|
| 18 | Â Â $e = xcache_get_special_value($src); |
|---|
| 19 | Â Â if (isset($e)) { |
|---|
| 20 | Â Â Â Â if (is_array($e)) { |
|---|
| 21 | Â Â Â Â Â Â $src = $e; |
|---|
| 22 | Â Â Â Â } |
|---|
| 23 | Â Â Â Â else { |
|---|
| 24 | Â Â Â Â Â Â return $e; |
|---|
| 25 | Â Â Â Â } |
|---|
| 26 | Â Â } |
|---|
| 27 | Â Â */ |
|---|
| 28 | |
|---|
| 29 |   if (is_array($src)) { |
|---|
| 30 | Â Â Â Â die_error('array str'); |
|---|
| 31 |     $src = new Decompiler_Array($src); |
|---|
| 32 |     return $src->__toString($indent); |
|---|
| 33 | Â Â } |
|---|
| 34 | |
|---|
| 35 |   if (is_object($src)) { |
|---|
| 36 |     if (!method_exists($src, '__toString')) { |
|---|
| 37 | Â Â Â Â Â Â var_dump($src); |
|---|
| 38 | Â Â Â Â Â Â die_error('no __toString'); |
|---|
| 39 | Â Â Â Â } |
|---|
| 40 |     return $src->__toString($indent); |
|---|
| 41 | Â Â } |
|---|
| 42 | |
|---|
| 43 |   return $src; |
|---|
| 44 | } |
|---|
| 45 | // }}} |
|---|
| 46 | function value($value) // {{{ |
|---|
| 47 | { |
|---|
| 48 |   $spec = xcache_get_special_value($value); |
|---|
| 49 |   if (isset($spec)) { |
|---|
| 50 |     $value = $spec; |
|---|
| 51 |     if (!is_array($value)) { |
|---|
| 52 | Â Â Â Â Â Â // constant |
|---|
| 53 |       return $value; |
|---|
| 54 | Â Â Â Â } |
|---|
| 55 | Â Â } |
|---|
| 56 | |
|---|
| 57 |   if (is_array($value)) { |
|---|
| 58 |     $value = new Decompiler_Array($value, true); |
|---|
| 59 | Â Â } |
|---|
| 60 |   else { |
|---|
| 61 |     $value = new Decompiler_Value($value, true); |
|---|
| 62 | Â Â } |
|---|
| 63 |   return $value; |
|---|
| 64 | } |
|---|
| 65 | // }}} |
|---|
| 66 | class Decompiler_Object // {{{ |
|---|
| 67 | { |
|---|
| 68 | } |
|---|
| 69 | // }}} |
|---|
| 70 | class Decompiler_Value extends Decompiler_Object // {{{ |
|---|
| 71 | { |
|---|
| 72 |   var $value; |
|---|
| 73 | |
|---|
| 74 |   function Decompiler_Value($value = null) |
|---|
| 75 | Â Â { |
|---|
| 76 |     $this->value = $value; |
|---|
| 77 | Â Â } |
|---|
| 78 | |
|---|
| 79 |   function __toString() |
|---|
| 80 | Â Â { |
|---|
| 81 |     return var_export($this->value, true); |
|---|
| 82 | Â Â } |
|---|
| 83 | } |
|---|
| 84 | // }}} |
|---|
| 85 | class Decompiler_Code extends Decompiler_Object // {{{ |
|---|
| 86 | { |
|---|
| 87 |   var $src; |
|---|
| 88 | |
|---|
| 89 |   function Decompiler_Code($src) |
|---|
| 90 | Â Â { |
|---|
| 91 |     $this->src = $src; |
|---|
| 92 | Â Â } |
|---|
| 93 | |
|---|
| 94 |   function __toString() |
|---|
| 95 | Â Â { |
|---|
| 96 |     return $this->src; |
|---|
| 97 | Â Â } |
|---|
| 98 | } |
|---|
| 99 | // }}} |
|---|
| 100 | class Decompiler_Binop extends Decompiler_Code // {{{ |
|---|
| 101 | { |
|---|
| 102 |   var $opc; |
|---|
| 103 |   var $op1; |
|---|
| 104 |   var $op2; |
|---|
| 105 |   var $parent; |
|---|
| 106 | |
|---|
| 107 |   function Decompiler_Binop($parent, $op1, $opc, $op2) |
|---|
| 108 | Â Â { |
|---|
| 109 |     $this->parent = &$parent; |
|---|
| 110 |     $this->opc = $opc; |
|---|
| 111 | Â Â Â Â $this->op1Â =Â $op1; |
|---|
| 112 | Â Â Â Â $this->op2Â =Â $op2; |
|---|
| 113 | Â Â } |
|---|
| 114 | |
|---|
| 115 |   function __toString() |
|---|
| 116 | Â Â { |
|---|
| 117 | Â Â Â Â $op1Â =Â str($this->op1); |
|---|
| 118 |     if (is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) { |
|---|
| 119 | Â Â Â Â Â Â $op1Â =Â "($op1)"; |
|---|
| 120 | Â Â Â Â } |
|---|
| 121 |     $opstr = $this->parent->binops[$this->opc]; |
|---|
| 122 |     if ($op1 == '0' && $this->opc == XC_SUB) { |
|---|
| 123 |       return $opstr . str($this->op2); |
|---|
| 124 | Â Â Â Â } |
|---|
| 125 |     return $op1 . ' ' . $opstr . ' ' . str($this->op2); |
|---|
| 126 | Â Â } |
|---|
| 127 | } |
|---|
| 128 | // }}} |
|---|
| 129 | class Decompiler_Fetch extends Decompiler_Code // {{{ |
|---|
| 130 | { |
|---|
| 131 |   var $src; |
|---|
| 132 |   var $fetchType; |
|---|
| 133 | |
|---|
| 134 |   function Decompiler_Fetch($src, $type, $globalsrc) |
|---|
| 135 | Â Â { |
|---|
| 136 |     $this->src = $src; |
|---|
| 137 |     $this->fetchType = $type; |
|---|
| 138 |     $this->globalsrc = $globalsrc; |
|---|
| 139 | Â Â } |
|---|
| 140 | |
|---|
| 141 |   function __toString() |
|---|
| 142 | Â Â { |
|---|
| 143 |     switch ($this->fetchType) { |
|---|
| 144 |     case ZEND_FETCH_LOCAL: |
|---|
| 145 |       return '$' . substr($this->src, 1, -1); |
|---|
| 146 |     case ZEND_FETCH_STATIC: |
|---|
| 147 | Â Â Â Â Â Â die('static fetch cant to string'); |
|---|
| 148 |     case ZEND_FETCH_GLOBAL: |
|---|
| 149 |     case ZEND_FETCH_GLOBAL_LOCK: |
|---|
| 150 |       return $this->globalsrc; |
|---|
| 151 | Â Â Â Â default: |
|---|
| 152 | Â Â Â Â Â Â var_dump($this->fetchType); |
|---|
| 153 | Â Â Â Â Â Â assert(0); |
|---|
| 154 | Â Â Â Â } |
|---|
| 155 | Â Â } |
|---|
| 156 | } |
|---|
| 157 | // }}} |
|---|
| 158 | class Decompiler_Box // {{{ |
|---|
| 159 | { |
|---|
| 160 |   var $obj; |
|---|
| 161 | |
|---|
| 162 |   function Decompiler_Box(&$obj) |
|---|
| 163 | Â Â { |
|---|
| 164 |     $this->obj = &$obj; |
|---|
| 165 | Â Â } |
|---|
| 166 | |
|---|
| 167 |   function __toString($indent) |
|---|
| 168 | Â Â { |
|---|
| 169 |     return $this->obj->__toString($indent); |
|---|
| 170 | Â Â } |
|---|
| 171 | } |
|---|
| 172 | // }}} |
|---|
| 173 | class Decompiler_Dim extends Decompiler_Value // {{{ |
|---|
| 174 | { |
|---|
| 175 |   var $offsets = array(); |
|---|
| 176 |   var $isLast = false; |
|---|
| 177 |   var $assign = null; |
|---|
| 178 | |
|---|
| 179 |   function __toString() |
|---|
| 180 | Â Â { |
|---|
| 181 |     if (is_a($this->value, 'Decompiler_ListBox')) { |
|---|
| 182 |       $exp = str($this->value->obj->src); |
|---|
| 183 | Â Â Â Â } |
|---|
| 184 |     else { |
|---|
| 185 |       $exp = str($this->value); |
|---|
| 186 | Â Â Â Â } |
|---|
| 187 |     foreach ($this->offsets as $dim) { |
|---|
| 188 |       $exp .= '[' . str($dim) . ']'; |
|---|
| 189 | Â Â Â Â } |
|---|
| 190 |     return $exp; |
|---|
| 191 | Â Â } |
|---|
| 192 | } |
|---|
| 193 | // }}} |
|---|
| 194 | class Decompiler_DimBox extends Decompiler_Box // {{{ |
|---|
| 195 | { |
|---|
| 196 | } |
|---|
| 197 | // }}} |
|---|
| 198 | class Decompiler_List extends Decompiler_Code // {{{ |
|---|
| 199 | { |
|---|
| 200 |   var $src; |
|---|
| 201 |   var $dims = array(); |
|---|
| 202 |   var $everLocked = false; |
|---|
| 203 | |
|---|
| 204 |   function __toString() |
|---|
| 205 | Â Â { |
|---|
| 206 |     if (count($this->dims) == 1 && !$this->everLocked) { |
|---|
| 207 |       $dim = $this->dims[0]; |
|---|
| 208 | Â Â Â Â Â Â unset($dim->value); |
|---|
| 209 |       $dim->value = $this->src; |
|---|
| 210 |       if (!isset($dim->assign)) { |
|---|
| 211 |         return str($dim); |
|---|
| 212 | Â Â Â Â Â Â } |
|---|
| 213 |       return str($this->dims[0]->assign) . ' = ' . str($dim); |
|---|
| 214 | Â Â Â Â } |
|---|
| 215 | Â Â Â Â /* flatten dims */ |
|---|
| 216 |     $assigns = array(); |
|---|
| 217 |     foreach ($this->dims as $dim) { |
|---|
| 218 |       $assign = &$assigns; |
|---|
| 219 |       foreach ($dim->offsets as $offset) { |
|---|
| 220 |         $assign = &$assign[$offset]; |
|---|
| 221 | Â Â Â Â Â Â } |
|---|
| 222 |       $assign = str($dim->assign); |
|---|
| 223 | Â Â Â Â } |
|---|
| 224 |     return $this->toList($assigns) . ' = ' . str($this->src); |
|---|
| 225 | Â Â } |
|---|
| 226 | |
|---|
| 227 |   function toList($assigns) |
|---|
| 228 | Â Â { |
|---|
| 229 |     $keys = array_keys($assigns); |
|---|
| 230 |     if (count($keys) < 2) { |
|---|
| 231 | Â Â Â Â Â Â $keys[]Â =Â 0; |
|---|
| 232 | Â Â Â Â } |
|---|
| 233 |     $max = call_user_func_array('max', $keys); |
|---|
| 234 |     $list = 'list('; |
|---|
| 235 |     for ($i = 0; $i <= $max; $i ++) { |
|---|
| 236 |       if ($i) { |
|---|
| 237 |         $list .= ', '; |
|---|
| 238 | Â Â Â Â Â Â } |
|---|
| 239 |       if (!isset($assigns[$i])) { |
|---|
| 240 | Â Â Â Â Â Â Â Â continue; |
|---|
| 241 | Â Â Â Â Â Â } |
|---|
| 242 |       if (is_array($assigns[$i])) { |
|---|
| 243 |         $list .= $this->toList($assigns[$i]); |
|---|
| 244 | Â Â Â Â Â Â } |
|---|
| 245 |       else { |
|---|
| 246 |         $list .= $assigns[$i]; |
|---|
| 247 | Â Â Â Â Â Â } |
|---|
| 248 | Â Â Â Â } |
|---|
| 249 |     return $list . ')'; |
|---|
| 250 | Â Â } |
|---|
| 251 | } |
|---|
| 252 | // }}} |
|---|
| 253 | class Decompiler_ListBox extends Decompiler_Box // {{{ |
|---|
| 254 | { |
|---|
| 255 | } |
|---|
| 256 | // }}} |
|---|
| 257 | class Decompiler_Array extends Decompiler_Value // {{{ |
|---|
| 258 | { |
|---|
| 259 |   var $needExport = false; |
|---|
| 260 | |
|---|
| 261 |   function Decompiler_Array($value = array(), $needexport = false) |
|---|
| 262 | Â Â { |
|---|
| 263 |     $this->value = $value; |
|---|
| 264 |     $this->needExport = $needexport; |
|---|
| 265 | Â Â } |
|---|
| 266 | |
|---|
| 267 |   function __toString($indent) |
|---|
| 268 | Â Â { |
|---|
| 269 |     $exp = "array("; |
|---|
| 270 |     $indent .= INDENT; |
|---|
| 271 |     $assoclen = 0; |
|---|
| 272 |     $multiline = 0; |
|---|
| 273 |     $i = 0; |
|---|
| 274 |     foreach ($this->value as $k => $v) { |
|---|
| 275 |       if ($i !== $k) { |
|---|
| 276 |         $len = strlen($k); |
|---|
| 277 |         if ($assoclen < $len) { |
|---|
| 278 |           $assoclen = $len; |
|---|
| 279 | Â Â Â Â Â Â Â Â } |
|---|
| 280 | Â Â Â Â Â Â } |
|---|
| 281 |       if (is_array($v)) { |
|---|
| 282 |         $multiline ++; |
|---|
| 283 | Â Â Â Â Â Â } |
|---|
| 284 | Â Â Â Â Â Â ++Â $i; |
|---|
| 285 | Â Â Â Â } |
|---|
| 286 |     if ($assoclen && $this->needExport) { |
|---|
| 287 |       $assoclen += 2; |
|---|
| 288 | Â Â Â Â } |
|---|
| 289 | |
|---|
| 290 |     $i = 0; |
|---|
| 291 |     $subindent = $indent . INDENT; |
|---|
| 292 |     foreach ($this->value as $k => $v) { |
|---|
| 293 |       if ($multiline) { |
|---|
| 294 |         if ($i) { |
|---|
| 295 |           $exp .= ","; |
|---|
| 296 | Â Â Â Â Â Â Â Â } |
|---|
| 297 |         $exp .= "\n"; |
|---|
| 298 |         $exp .= $indent; |
|---|
| 299 | Â Â Â Â Â Â } |
|---|
| 300 |       else { |
|---|
| 301 |         if ($i) { |
|---|
| 302 |           $exp .= ", "; |
|---|
| 303 | Â Â Â Â Â Â Â Â } |
|---|
| 304 | Â Â Â Â Â Â } |
|---|
| 305 | |
|---|
| 306 |       if ($this->needExport) { |
|---|
| 307 |         $k = var_export($k, true); |
|---|
| 308 | Â Â Â Â Â Â } |
|---|
| 309 |       if ($multiline) { |
|---|
| 310 |         $exp .= sprintf("%{$assoclen}s => ", $k); |
|---|
| 311 | Â Â Â Â Â Â } |
|---|
| 312 |       else if ($assoclen) { |
|---|
| 313 |         $exp .= $k . ' => '; |
|---|
| 314 | Â Â Â Â Â Â } |
|---|
| 315 | |
|---|
| 316 |       if (is_array($v)) { |
|---|
| 317 |         $v = new Decompiler_Array($v, $this->needExport); |
|---|
| 318 | Â Â Â Â Â Â } |
|---|
| 319 |       $exp .= str($v, $subindent); |
|---|
| 320 | |
|---|
| 321 |       $i ++; |
|---|
| 322 | Â Â Â Â } |
|---|
| 323 |     if ($multiline) { |
|---|
| 324 |       $exp .= "$indent);"; |
|---|
| 325 | Â Â Â Â } |
|---|
| 326 |     else { |
|---|
| 327 |       $exp .= ")"; |
|---|
| 328 | Â Â Â Â } |
|---|
| 329 |     return $exp; |
|---|
| 330 | Â Â } |
|---|
| 331 | } |
|---|
| 332 | // }}} |
|---|
| 333 | class Decompiler_ForeachBox extends Decompiler_Box // {{{ |
|---|
| 334 | { |
|---|
| 335 |   var $iskey; |
|---|
| 336 | |
|---|
| 337 |   function __toString($indent) |
|---|
| 338 | Â Â { |
|---|
| 339 |     return 'foreach (' . ''; |
|---|
| 340 | Â Â } |
|---|
| 341 | } |
|---|
| 342 | // }}} |
|---|
| 343 | |
|---|
| 344 | class Decompiler |
|---|
| 345 | { |
|---|
| 346 |   var $rName = '!^[\\w_][\\w\\d_]*$!'; |
|---|
| 347 |   var $rQuotedName = "!^'[\\w_][\\w\\d_]*'\$!"; |
|---|
| 348 | |
|---|
| 349 |   function Decompiler() |
|---|
| 350 | Â Â { |
|---|
| 351 | Â Â Â Â // {{{ opinfo |
|---|
| 352 |     $this->unaryops = array( |
|---|
| 353 | Â Â Â Â Â Â Â Â XC_BW_NOTÂ Â =>Â '~', |
|---|
| 354 | Â Â Â Â Â Â Â Â XC_BOOL_NOTÂ =>Â '!', |
|---|
| 355 | Â Â Â Â Â Â Â Â ); |
|---|
| 356 |     $this->binops = array( |
|---|
| 357 | Â Â Â Â Â Â Â Â XC_ADDÂ Â Â Â Â Â Â Â Â =>Â "+", |
|---|
| 358 | Â Â Â Â Â Â Â Â XC_ASSIGN_ADDÂ Â Â Â Â =>Â "+=", |
|---|
| 359 | Â Â Â Â Â Â Â Â XC_SUBÂ Â Â Â Â Â Â Â Â =>Â "-", |
|---|
| 360 | Â Â Â Â Â Â Â Â XC_ASSIGN_SUBÂ Â Â Â Â =>Â "-=", |
|---|
| 361 | Â Â Â Â Â Â Â Â XC_MULÂ Â Â Â Â Â Â Â Â =>Â "*", |
|---|
| 362 | Â Â Â Â Â Â Â Â XC_ASSIGN_MULÂ Â Â Â Â =>Â "*=", |
|---|
| 363 | Â Â Â Â Â Â Â Â XC_DIVÂ Â Â Â Â Â Â Â Â =>Â "/", |
|---|
| 364 | Â Â Â Â Â Â Â Â XC_ASSIGN_DIVÂ Â Â Â Â =>Â "/=", |
|---|
| 365 | Â Â Â Â Â Â Â Â XC_MODÂ Â Â Â Â Â Â Â Â =>Â "%", |
|---|
| 366 | Â Â Â Â Â Â Â Â XC_ASSIGN_MODÂ Â Â Â Â =>Â "%=", |
|---|
| 367 | Â Â Â Â Â Â Â Â XC_SLÂ Â Â Â Â Â Â Â Â =>Â "<<", |
|---|
| 368 | Â Â Â Â Â Â Â Â XC_ASSIGN_SLÂ Â Â Â Â Â =>Â "<<=", |
|---|
| 369 | Â Â Â Â Â Â Â Â XC_SRÂ Â Â Â Â Â Â Â Â =>Â ">>", |
|---|
| 370 | Â Â Â Â Â Â Â Â XC_ASSIGN_SRÂ Â Â Â Â Â =>Â ">>=", |
|---|
| 371 | Â Â Â Â Â Â Â Â XC_CONCATÂ Â Â Â Â Â Â =>Â ".", |
|---|
| 372 | Â Â Â Â Â Â Â Â XC_ASSIGN_CONCATÂ Â Â Â =>Â ".=", |
|---|
| 373 | Â Â Â Â Â Â Â Â XC_IS_IDENTICALÂ Â Â Â =>Â "===", |
|---|
| 374 | Â Â Â Â Â Â Â Â XC_IS_NOT_IDENTICALÂ Â =>Â "!==", |
|---|
| 375 | Â Â Â Â Â Â Â Â XC_IS_EQUALÂ Â Â Â Â Â =>Â "==", |
|---|
| 376 | Â Â Â Â Â Â Â Â XC_IS_NOT_EQUALÂ Â Â Â =>Â "!=", |
|---|
| 377 | Â Â Â Â Â Â Â Â XC_IS_SMALLERÂ Â Â Â Â =>Â "<", |
|---|
| 378 | Â Â Â Â Â Â Â Â XC_IS_SMALLER_OR_EQUALÂ =>Â "<=", |
|---|
| 379 | Â Â Â Â Â Â Â Â XC_BW_ORÂ Â Â Â Â Â Â Â =>Â "|", |
|---|
| 380 | Â Â Â Â Â Â Â Â XC_ASSIGN_BW_ORÂ Â Â Â =>Â "|=", |
|---|
| 381 | Â Â Â Â Â Â Â Â XC_BW_ANDÂ Â Â Â Â Â Â =>Â "&", |
|---|
| 382 | Â Â Â Â Â Â Â Â XC_ASSIGN_BW_ANDÂ Â Â Â =>Â "&=", |
|---|
| 383 | Â Â Â Â Â Â Â Â XC_BW_XORÂ Â Â Â Â Â Â =>Â "^", |
|---|
| 384 | Â Â Â Â Â Â Â Â XC_ASSIGN_BW_XORÂ Â Â Â =>Â "^=", |
|---|
| 385 | Â Â Â Â Â Â Â Â XC_BOOL_XORÂ Â Â Â Â Â =>Â "xor", |
|---|
| 386 | Â Â Â Â Â Â Â Â ); |
|---|
| 387 | Â Â Â Â // }}} |
|---|
| 388 |     $this->includeTypes = array( // {{{ |
|---|
| 389 | Â Â Â Â Â Â Â Â ZEND_EVALÂ Â Â Â Â =>Â 'eval', |
|---|
| 390 | Â Â Â Â Â Â Â Â ZEND_INCLUDEÂ Â Â =>Â 'include', |
|---|
| 391 | Â Â Â Â Â Â Â Â ZEND_INCLUDE_ONCEÂ =>Â 'include_once', |
|---|
| 392 | Â Â Â Â Â Â Â Â ZEND_REQUIREÂ Â Â =>Â 'require', |
|---|
| 393 | Â Â Â Â Â Â Â Â ZEND_REQUIRE_ONCEÂ =>Â 'require_once', |
|---|
| 394 | Â Â Â Â Â Â Â Â ); |
|---|
| 395 | Â Â Â Â Â Â Â Â // }}} |
|---|
| 396 | Â Â } |
|---|
| 397 |   function outputPhp(&$opcodes, $opline, $last, $indent) // {{{ |
|---|
| 398 | Â Â { |
|---|
| 399 |     $origindent = $indent; |
|---|
| 400 |     $curticks = 0; |
|---|
| 401 |     for ($i = $opline; $i <= $last; $i ++) { |
|---|
| 402 |       $op = $opcodes[$i]; |
|---|
| 403 |       if (isset($op['php'])) { |
|---|
| 404 |         $toticks = isset($op['ticks']) ? $op['ticks'] : 0; |
|---|
| 405 |         if ($curticks != $toticks) { |
|---|
| 406 |           if (!$toticks) { |
|---|
| 407 |             echo $origindent, "}\n"; |
|---|
| 408 |             $indent = $origindent; |
|---|
| 409 | Â Â Â Â Â Â Â Â Â Â } |
|---|
| 410 |           else { |
|---|
| 411 |             if ($curticks) { |
|---|
| 412 |               echo $origindent, "}\n"; |
|---|
| 413 | Â Â Â Â Â Â Â Â Â Â Â Â } |
|---|
| 414 |             else if (!$curticks) { |
|---|
| 415 |               $indent .= INDENT; |
|---|
| 416 | Â Â Â Â Â Â Â Â Â Â Â Â } |
|---|
| 417 |             echo $origindent, "declare(ticks=$curticks) {\n"; |
|---|
| 418 | Â Â Â Â Â Â Â Â Â Â } |
|---|
| 419 |           $curticks = $toticks; |
|---|
| 420 | Â Â Â Â Â Â Â Â } |
|---|
| 421 |         echo $indent, str($op['php']), ";\n"; |
|---|
| 422 | Â Â Â Â Â Â } |
|---|
| 423 | Â Â Â Â } |
|---|
| 424 |     if ($curticks) { |
|---|
| 425 |       echo $origindent, "}\n"; |
|---|
| 426 | Â Â Â Â } |
|---|
| 427 | Â Â } |
|---|
| 428 | Â Â // }}} |
|---|
| 429 |   function getOpVal($op, &$EX, $tostr = true, $free = false) // {{{ |
|---|
| 430 | Â Â { |
|---|
| 431 |     switch ($op['op_type']) { |
|---|
| 432 |     case XC_IS_CONST: |
|---|
| 433 |       return str(value($op['u.constant'])); |
|---|
| 434 | |
|---|
| 435 |     case XC_IS_VAR: |
|---|
| 436 |     case XC_IS_TMP_VAR: |
|---|
| 437 | Â Â Â Â Â Â $TÂ =Â &$EX['Ts']; |
|---|
| 438 |       $ret = $T[$op['u.var']]; |
|---|
| 439 |       if ($tostr) { |
|---|
| 440 |         $ret = str($ret, $EX); |
|---|
| 441 | Â Â Â Â Â Â } |
|---|
| 442 |       if ($free) { |
|---|
| 443 | Â Â Â Â Â Â Â Â unset($T[$op['u.var']]); |
|---|
| 444 | Â Â Â Â Â Â } |
|---|
| 445 |       return $ret; |
|---|
| 446 | |
|---|
| 447 |     case XC_IS_CV: |
|---|
| 448 |       $var = $op['u.var']; |
|---|
| 449 |       $var = $EX['op_array']['vars'][$var]; |
|---|
| 450 |       return '$' . $var['name']; |
|---|
| 451 | |
|---|
| 452 |     case XC_IS_UNUSED: |
|---|
| 453 |       return null; |
|---|
| 454 | Â Â Â Â } |
|---|
| 455 | Â Â } |
|---|
| 456 | Â Â // }}} |
|---|
| 457 |   function &dop_array($op_array, $indent = '') // {{{ |
|---|
| 458 | Â Â { |
|---|
| 459 |     $opcodes = &$op_array['opcodes']; |
|---|
| 460 |     $last = count($opcodes) - 1; |
|---|
| 461 |     if ($opcodes[$last]['opcode'] == XC_HANDLE_EXCEPTION) { |
|---|
| 462 | Â Â Â Â Â Â unset($opcodes[$last]); |
|---|
| 463 | Â Â Â Â } |
|---|
| 464 | Â Â Â Â $EX['indent']Â =Â ''; |
|---|
| 465 | Â Â Â Â //for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) { |
|---|
| 466 | Â Â Â Â //Â $opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i); |
|---|
| 467 | Â Â Â Â //} |
|---|
| 468 | Â Â Â Â // {{{ build jmp array |
|---|
| 469 |     for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) { |
|---|
| 470 |       $op = &$opcodes[$i]; |
|---|
| 471 | Â Â Â Â Â Â /* |
|---|
| 472 | Â Â Â Â Â Â if ($op['opcode'] == XC_JMPZ) { |
|---|
| 473 | Â Â Â Â Â Â Â Â $this->dumpop($op, $EX); |
|---|
| 474 | Â Â Â Â Â Â Â Â var_dump($op); |
|---|
| 475 | Â Â Â Â Â Â } |
|---|
| 476 | Â Â Â Â Â Â continue; |
|---|
| 477 | Â Â Â Â Â Â */ |
|---|
| 478 | Â Â Â Â Â Â $op['line']Â =Â $i; |
|---|
| 479 |       switch ($op['opcode']) { |
|---|
| 480 |       case XC_JMP: |
|---|
| 481 |         $target = $op['op1']['u.var']; |
|---|
| 482 | Â Â Â Â Â Â Â Â $op['jmpouts']Â =Â array($target); |
|---|
| 483 | Â Â Â Â Â Â Â Â $opcodes[$target]['jmpins'][]Â =Â $i; |
|---|
| 484 | Â Â Â Â Â Â Â Â break; |
|---|
| 485 | |
|---|
| 486 |       case XC_JMPZNZ: |
|---|
| 487 |         $jmpz = $op['op2']['u.opline_num']; |
|---|
| 488 |         $jmpnz = $op['extended_value']; |
|---|
| 489 |         $op['jmpouts'] = array($jmpz, $jmpnz); |
|---|
| 490 | Â Â Â Â Â Â Â Â $opcodes[$jmpz]['jmpins'][]Â =Â $i; |
|---|
| 491 | Â Â Â Â Â Â Â Â $opcodes[$jmpnz]['jmpins'][]Â =Â $i; |
|---|
| 492 | Â Â Â Â Â Â Â Â break; |
|---|
| 493 | |
|---|
| 494 |       case XC_JMPZ: |
|---|
| 495 |       case XC_JMPNZ: |
|---|
| 496 |       case XC_JMPZ_EX: |
|---|
| 497 |       case XC_JMPNZ_EX: |
|---|
| 498 | Â Â Â Â Â Â // case XC_FE_RESET: |
|---|
| 499 |       case XC_FE_FETCH: |
|---|
| 500 | Â Â Â Â Â Â // case XC_JMP_NO_CTOR: |
|---|
| 501 |         $target = $op['op2']['u.opline_num']; |
|---|
| 502 | Â Â Â Â Â Â Â Â //if (!isset($target)) { |
|---|
| 503 | Â Â Â Â Â Â Â Â //Â $this->dumpop($op, $EX); |
|---|
| 504 | Â Â Â Â Â Â Â Â //Â var_dump($op); exit; |
|---|
| 505 | Â Â Â Â Â Â Â Â //} |
|---|
| 506 | Â Â Â Â Â Â Â Â $op['jmpouts']Â =Â array($target); |
|---|
| 507 | Â Â Â Â Â Â Â Â $opcodes[$target]['jmpins'][]Â =Â $i; |
|---|
| 508 | Â Â Â Â Â Â Â Â break; |
|---|
| 509 | |
|---|
| 510 | Â Â Â Â Â Â /* |
|---|
| 511 | Â Â Â Â Â Â case XC_RETURN: |
|---|
| 512 | Â Â Â Â Â Â Â Â $op['jmpouts'] = array(); |
|---|
| 513 | Â Â Â Â Â Â Â Â break; |
|---|
| 514 | Â Â Â Â Â Â */ |
|---|
| 515 | Â Â Â Â Â Â } |
|---|
| 516 | Â Â Â Â } |
|---|
| 517 | Â Â Â Â unset($op); |
|---|
| 518 | Â Â Â Â // }}} |
|---|
| 519 | Â Â Â Â // build semi-basic blocks |
|---|
| 520 |     $nextbbs = array(); |
|---|
| 521 |     $starti = 0; |
|---|
| 522 |     for ($i = 1, $cnt = count($opcodes); $i < $cnt; $i ++) { |
|---|
| 523 |       if (isset($opcodes[$i]['jmpins']) |
|---|
| 524 |        || isset($opcodes[$i - 1]['jmpouts'])) { |
|---|
| 525 | Â Â Â Â Â Â Â Â $nextbbs[$starti]Â =Â $i; |
|---|
| 526 |         $starti = $i; |
|---|
| 527 | Â Â Â Â Â Â } |
|---|
| 528 | Â Â Â Â } |
|---|
| 529 | Â Â Â Â $nextbbs[$starti]Â =Â $cnt; |
|---|
| 530 | |
|---|
| 531 | Â Â Â Â $EXÂ =Â array(); |
|---|
| 532 | Â Â Â Â $EX['Ts']Â =Â array(); |
|---|
| 533 | Â Â Â Â $EX['indent']Â =Â $indent; |
|---|
| 534 | Â Â Â Â $EX['nextbbs']Â =Â $nextbbs; |
|---|
| 535 | Â Â Â Â $EX['op_array']Â =Â &$op_array; |
|---|
| 536 | Â Â Â Â $EX['opcodes']Â =Â &$opcodes; |
|---|
| 537 | Â Â Â Â // func call |
|---|
| 538 | Â Â Â Â $EX['object']Â =Â null; |
|---|
| 539 | Â Â Â Â $EX['fbc']Â =Â null; |
|---|
| 540 | Â Â Â Â $EX['argstack']Â =Â array(); |
|---|
| 541 | Â Â Â Â $EX['arg_types_stack']Â =Â array(); |
|---|
| 542 | Â Â Â Â $EX['last']Â =Â count($opcodes)Â -Â 1; |
|---|
| 543 | Â Â Â Â $EX['silence']Â =Â 0; |
|---|
| 544 | |
|---|
| 545 |     for ($next = 0, $last = $EX['last']; |
|---|
| 546 |         $loop = $this->outputCode($EX, $next, $last, $indent, true); |
|---|
| 547 |         list($next, $last) = $loop) { |
|---|
| 548 | Â Â Â Â Â Â // empty |
|---|
| 549 | Â Â Â Â } |
|---|
| 550 |     return $EX; |
|---|
| 551 | Â Â } |
|---|
| 552 | Â Â // }}} |
|---|
| 553 |   function outputCode(&$EX, $opline, $last, $indent, $loop = false) // {{{ |
|---|
| 554 | Â Â { |
|---|
| 555 |     $op = &$EX['opcodes'][$opline]; |
|---|
| 556 |     $next = $EX['nextbbs'][$opline]; |
|---|
| 557 | |
|---|
| 558 |     $end = $next - 1; |
|---|
| 559 |     if ($end > $last) { |
|---|
| 560 |       $end = $last; |
|---|
| 561 | Â Â Â Â } |
|---|
| 562 | |
|---|
| 563 |     if (isset($op['jmpins'])) { |
|---|
| 564 |       echo "\nline", $op['line'], ":\n"; |
|---|
| 565 | Â Â Â Â } |
|---|
| 566 |     else { |
|---|
| 567 | Â Â Â Â Â Â // echo ";;;\n"; |
|---|
| 568 | Â Â Â Â } |
|---|
| 569 |     $this->dasmBasicBlock($EX, $opline, $end); |
|---|
| 570 |     $this->outputPhp($EX['opcodes'], $opline, $end, $indent); |
|---|
| 571 | Â Â Â Â // jmpout op |
|---|
| 572 |     $op = &$EX['opcodes'][$end]; |
|---|
| 573 | Â Â Â Â $op1Â =Â $op['op1']; |
|---|
| 574 | Â Â Â Â $op2Â =Â $op['op2']; |
|---|
| 575 |     $ext = $op['extended_value']; |
|---|
| 576 |     $line = $op['line']; |
|---|
| 577 | |
|---|
| 578 |     if (isset($EX['opcodes'][$next])) { |
|---|
| 579 |       if (isset($last) && $next > $last) { |
|---|
| 580 |         $next = null; |
|---|
| 581 | Â Â Â Â Â Â } |
|---|
| 582 | Â Â Â Â } |
|---|
| 583 |     else { |
|---|
| 584 |       $next = null; |
|---|
| 585 | Â Â Â Â } |
|---|
| 586 |     if ($op['opcode'] == XC_FE_FETCH) { |
|---|
| 587 |       $opline = $next; |
|---|
| 588 |       $next = $op['op2']['u.opline_num']; |
|---|
| 589 |       $end = $next - 1; |
|---|
| 590 | |
|---|
| 591 | Â Â Â Â Â Â ob_start(); |
|---|
| 592 |       $this->outputCode($EX, $opline, $end /* - 1 skip last jmp */, $indent . INDENT); |
|---|
| 593 |       $body = ob_get_clean(); |
|---|
| 594 | |
|---|
| 595 |       $as = str($op['fe_as']); |
|---|
| 596 |       if (isset($op['fe_key'])) { |
|---|
| 597 |         $as = str($op['fe_key']) . ' => ' . $as; |
|---|
| 598 | Â Â Â Â Â Â } |
|---|
| 599 |       echo "{$indent}foreach (" . str($op['fe_src']) . " as $as) {\n"; |
|---|
| 600 |       echo $body; |
|---|
| 601 |       echo "{$indent}}"; |
|---|
| 602 | Â Â Â Â Â Â // $this->outputCode($EX, $next, $last, $indent); |
|---|
| 603 | Â Â Â Â Â Â // return; |
|---|
| 604 | Â Â Â Â } |
|---|
| 605 | Â Â Â Â /* |
|---|
| 606 | Â Â Â Â if ($op['opcode'] == XC_JMPZ) { |
|---|
| 607 | Â Â Â Â Â Â $target = $op2['u.opline_num']; |
|---|
| 608 | Â Â Â Â Â Â if ($line + 1) { |
|---|
| 609 | Â Â Â Â Â Â Â Â $nextblock = $EX['nextbbs'][$next]; |
|---|
| 610 | Â Â Â Â Â Â Â Â $jmpop = end($nextblock); |
|---|
| 611 | Â Â Â Â Â Â Â Â if ($jmpop['opcode'] == XC_JMP) { |
|---|
| 612 | Â Â Â Â Â Â Â Â Â Â $ifendline = $op2['u.opline_num']; |
|---|
| 613 | Â Â Â Â Â Â Â Â Â Â if ($ifendline >= $line) { |
|---|
| 614 | Â Â Â Â Â Â Â Â Â Â Â Â $cond = $op['cond']; |
|---|
| 615 | Â Â Â Â Â Â Â Â Â Â Â Â echo "{$indent}if ($cond) {\n"; |
|---|
| 616 | Â Â Â Â Â Â Â Â Â Â Â Â $this->outputCode($EX, $next, $last, INDENT . $indent); |
|---|
| 617 | Â Â Â Â Â Â Â Â Â Â Â Â echo "$indent}\n"; |
|---|
| 618 | Â Â Â Â Â Â Â Â Â Â Â Â $this->outputCode($EX, $target, $last, $indent); |
|---|
| 619 | Â Â Â Â Â Â Â Â Â Â Â Â return; |
|---|
| 620 | Â Â Â Â Â Â Â Â Â Â } |
|---|
| 621 | Â Â Â Â Â Â Â Â } |
|---|
| 622 | Â Â Â Â Â Â } |
|---|
| 623 | Â Â Â Â } |
|---|
| 624 | Â Â Â Â */ |
|---|
| 625 |     if (!isset($next)) { |
|---|
| 626 | Â Â Â Â Â Â return; |
|---|
| 627 | Â Â Â Â } |
|---|
| 628 |     if (!empty($op['jmpouts']) && isset($op['isjmp'])) { |
|---|
| 629 |       if (isset($op['cond'])) { |
|---|
| 630 |         echo "{$indent}check ($op[cond]) {\n"; |
|---|
| 631 |         echo INDENT; |
|---|
| 632 | Â Â Â Â Â Â } |
|---|
| 633 |       echo $indent; |
|---|
| 634 |       echo xcache_get_opcode($op['opcode']), ' line', $op['jmpouts'][0]; |
|---|
| 635 |       if (isset($op['jmpouts'][1])) { |
|---|
| 636 |         echo ', line', $op['jmpouts'][1]; |
|---|
| 637 | Â Â Â Â Â Â } |
|---|
| 638 |       echo ";"; |
|---|
| 639 | Â Â Â Â Â Â // echo ' // <- line', $op['line']; |
|---|
| 640 |       echo "\n"; |
|---|
| 641 |       if (isset($op['cond'])) echo "$indent}\n"; |
|---|
| 642 | Â Â Â Â } |
|---|
| 643 | |
|---|
| 644 | Â Â Â Â // proces JMPZ_EX/JMPNZ_EX for AND,OR |
|---|
| 645 |     $op = &$EX['opcodes'][$next]; |
|---|
| 646 | Â Â Â Â /* |
|---|
| 647 | Â Â Â Â if (isset($op['jmpins'])) { |
|---|
| 648 | Â Â Â Â Â Â foreach (array_reverse($op['jmpins']) as $fromline) { |
|---|
| 649 | Â Â Â Â Â |
|---|