/** * Calls static methods on the 'self/static' context * * @param string $context SELF / STATIC * @param string $methodName * @param array $expression * @param Variable $symbolVariable * @param boolean $mustInit * @param boolean $isExpecting * @param ClassDefinition $classDefinition * @param CompilationContext $compilationContext * @param ClassMethod $method */ protected function call($context, $methodName, array $expression, $symbolVariable, $mustInit, $isExpecting, ClassDefinition $classDefinition, CompilationContext $compilationContext, ClassMethod $method) { if (!in_array($context, array('SELF', 'STATIC'))) { $context = 'SELF'; } $codePrinter = $compilationContext->codePrinter; /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); if ($mustInit) { $symbolVariable->setMustInitNull(true); $symbolVariable->trackVariant($compilationContext); } /** * Check if the method call can have an inline cache */ $methodCache = $compilationContext->cacheManager->getStaticMethodCache(); $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null, false); if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); } else { $params = array(); } $isInternal = false; if (isset($method)) { $isInternal = $method->isInternal(); } if (!$isInternal) { if (!count($params)) { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_' . $context . '("' . $methodName . '", ' . $cachePointer . ');'); } else { $codePrinter->output('ZEPHIR_CALL_' . $context . '(&' . $symbolVariable->getName() . ', "' . $methodName . '", ' . $cachePointer . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_' . $context . '(NULL, "' . $methodName . '", ' . $cachePointer . ');'); } } else { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_' . $context . '("' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');'); } else { $codePrinter->output('ZEPHIR_CALL_' . $context . '(&' . $symbolVariable->getName() . ', "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_' . $context . '(NULL, "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');'); } } } else { if (!count($params)) { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_INTERNAL_METHOD_P0(EG(This), ' . $method->getInternalName() . ');'); } else { $codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_P0(&' . $symbolVariable->getName() . ', EG(This), ' . $method->getInternalName() . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_NORETURN_P0(EG(This), ' . $method->getInternalName() . ');'); } } else { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_INTERNAL_METHOD_P' . count($params) . '(EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');'); } else { $codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_P' . count($params) . '(&' . $symbolVariable->getName() . ', EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_NORETURN_P' . count($params) . '(EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');'); } } } /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { $codePrinter->output('zephir_check_temp_parameter(' . $checkVariable . ');'); } $this->addCallStatusOrJump($compilationContext); }
/** * Returns the signature of an internal method */ public function getInternalSignature(ClassMethod $method, CompilationContext $context) { if ($method->isInitializer() && !$method->isStatic()) { return 'static zend_object *' . $method->getName() . '(zend_class_entry *class_type TSRMLS_DC)'; } if ($method->isInitializer() && $method->isStatic()) { return 'void ' . $method->getName() . '(TSRMLS_D)'; } $signatureParameters = array(); $parameters = $method->getParameters(); if (is_object($parameters)) { foreach ($parameters->getParameters() as $parameter) { switch ($parameter['data-type']) { case 'int': case 'uint': case 'long': case 'double': case 'bool': case 'char': case 'uchar': case 'string': case 'array': $signatureParameters[] = 'zval *' . $parameter['name'] . '_param_ext'; break; default: $signatureParameters[] = 'zval *' . $parameter['name'] . '_ext '; break; } } } if (count($signatureParameters)) { return 'void ' . $method->getInternalName() . '(int ht, zval *return_value, zval *this_ptr, int return_value_used, ' . join(', ', $signatureParameters) . ')'; } return 'void ' . $method->getInternalName() . '(int ht, zval *return_value, zval *this_ptr, int return_value_used)'; }
/** * Returns the signature of an internal method * * @return string */ private function getInternalSignature(ClassMethod $method) { if ($method->getName() == 'zephir_init_properties') { return 'static zend_object_value ' . $method->getName() . '(zend_class_entry *class_type TSRMLS_DC)'; } if ($method->getName() == 'zephir_init_static_properties') { $classDefinition = $method->getClassDefinition(); return 'void ' . $method->getName() . '_' . $classDefinition->getCNamespace() . '_' . $classDefinition->getName() . '(TSRMLS_D)'; } $signatureParameters = array(); $parameters = $method->getParameters(); if (is_object($parameters)) { foreach ($parameters->getParameters() as $parameter) { switch ($parameter['data-type']) { case 'int': case 'uint': case 'long': case 'double': case 'bool': case 'char': case 'uchar': $signatureParameters[] = 'zval *' . $parameter['name'] . '_param_ext'; break; default: $signatureParameters[] = 'zval *' . $parameter['name'] . '_ext'; break; } } } if (count($signatureParameters)) { return 'static void ' . $method->getInternalName() . '(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used, ' . join(', ', $signatureParameters) . ' TSRMLS_DC)'; } return 'static void ' . $method->getInternalName() . '(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC)'; }