void ClassStatement::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { ClassScopeRawPtr classScope = getClassScope(); if (!classScope->isUserClass()) return; switch (m_type) { case T_CLASS: break; case T_ABSTRACT: cg_printf("abstract "); break; case T_FINAL: cg_printf("final "); break; default: ASSERT(false); } cg_printf("class %s", m_originalName.c_str()); if (!m_parent.empty()) { cg_printf(" extends %s", m_originalParent.c_str()); } if (m_base) { cg_printf(" implements "); m_base->outputPHP(cg, ar); } cg_indentBegin(" {\n"); classScope->outputPHP(cg, ar); if (m_stmt) m_stmt->outputPHP(cg, ar); cg_indentEnd("}\n"); }
void ClassStatement::outputCPPClassDecl(CodeGenerator &cg, AnalysisResultPtr ar, const char *clsName, const char *originalName, const char *parent) { ClassScopeRawPtr classScope = getClassScope(); VariableTablePtr variables = classScope->getVariables(); ConstantTablePtr constants = classScope->getConstants(); const char *sweep = classScope->isUserClass() && !classScope->isSepExtension() ? "_NO_SWEEP" : ""; if (variables->hasAllJumpTables() && classScope->hasAllJumpTables()) { cg_printf("DECLARE_CLASS%s(%s, %s, %s)\n", sweep, clsName, CodeGenerator::EscapeLabel(originalName).c_str(), parent); return; } // Now we start to break down DECLARE_CLASS into lines of code that could // be generated differently... cg_printf("DECLARE_CLASS_COMMON%s(%s, %s)\n", sweep, clsName, CodeGenerator::EscapeLabel(originalName).c_str()); }
TypePtr Symbol::setType(AnalysisResultConstPtr ar, BlockScopeRawPtr scope, TypePtr type, bool coerced) { if (!type) return type; if (ar->getPhase() == AnalysisResult::FirstInference) { // at this point, you *must* have a lock (if you are user scope) if (scope->is(BlockScope::FunctionScope)) { FunctionScopeRawPtr f = static_pointer_cast<FunctionScope>(scope); if (f->isUserFunction()) { f->getInferTypesMutex().assertOwnedBySelf(); } } else if (scope->is(BlockScope::ClassScope)) { ClassScopeRawPtr c = static_pointer_cast<ClassScope>(scope); if (c->isUserClass()) { c->getInferTypesMutex().assertOwnedBySelf(); } } } TypePtr oldType = m_coerced; if (!oldType) oldType = Type::Some; if (!coerced) return oldType; type = CoerceTo(ar, m_coerced, type); assert(!isRefClosureVar() || (type && type->is(Type::KindOfVariant))); if (ar->getPhase() >= AnalysisResult::AnalyzeAll && !Type::SameType(oldType, type)) { triggerUpdates(scope); } return type; }
void InterfaceStatement::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { ClassScopeRawPtr classScope = getClassScope(); if (cg.getOutput() == CodeGenerator::InlinedPHP || cg.getOutput() == CodeGenerator::TrimmedPHP) { if (!classScope->isUserClass()) { return; } } cg_printf("interface %s", m_originalName.c_str()); if (m_base) { cg_printf(" extends "); m_base->outputPHP(cg, ar); } cg_indentBegin(" {\n"); classScope->outputPHP(cg, ar); if (m_stmt) m_stmt->outputPHP(cg, ar); cg_indentEnd("}\n"); }
void ClassStatement::outputCPPClassDecl(CodeGenerator &cg, AnalysisResultPtr ar, const char *clsName, const char *originalName, const char *parent) { ClassScopeRawPtr classScope = getClassScope(); VariableTablePtr variables = classScope->getVariables(); ConstantTablePtr constants = classScope->getConstants(); const char *sweep = classScope->isUserClass() && !classScope->isSepExtension() ? "_NO_SWEEP" : ""; if (variables->hasAllJumpTables() && classScope->hasAllJumpTables()) { cg_printf("DECLARE_CLASS%s(%s, %s, %s)\n", sweep, clsName, CodeGenerator::EscapeLabel(originalName).c_str(), parent); return; } // Now we start to break down DECLARE_CLASS into lines of code that could // be generated differently... cg_printf("DECLARE_CLASS_COMMON%s(%s, %s)\n", sweep, clsName, CodeGenerator::EscapeLabel(originalName).c_str()); cg.printSection("DECLARE_STATIC_PROP_OPS"); cg_printf("public:\n"); cg.printSection("DECLARE_COMMON_INVOKE"); if (classScope->hasJumpTable(ClassScope::JumpTableCallInfo)) { cg.printf("static const MethodCallInfoTable s_call_info_table[];\n"); cg.printf("static const int s_call_info_index[];\n"); } else { cg.printf("static const int s_call_info_table = 0;\n"); cg.printf("static const int s_call_info_index = 0;\n"); } cg_printf("\n"); cg_printf("public:\n"); }
void ClassStatement::outputCPPClassDecl(CodeGenerator &cg, AnalysisResultPtr ar, const char *clsName, const char *originalName, const char *parent) { ClassScopeRawPtr classScope = getClassScope(); VariableTablePtr variables = classScope->getVariables(); ConstantTablePtr constants = classScope->getConstants(); const char *sweep = classScope->isUserClass() && !classScope->isSepExtension() ? "_NO_SWEEP" : ""; if (variables->hasAllJumpTables() && constants->hasJumpTable() && classScope->hasAllJumpTables()) { cg_printf("DECLARE_CLASS%s(%s, %s, %s)\n", sweep, clsName, originalName, parent); return; } // Now we start to break down DECLARE_CLASS into lines of code that could // be generated differently... cg_printf("DECLARE_CLASS_COMMON%s(%s, %s)\n", sweep, clsName, CodeGenerator::EscapeLabel(originalName).c_str()); cg_printf("DECLARE_INVOKE_EX%s(%s, %s, %s)\n", Option::UseMethodIndex ? "WITH_INDEX" : "", clsName, CodeGenerator::EscapeLabel(originalName).c_str(), parent); cg.printSection("DECLARE_STATIC_PROP_OPS"); cg_printf("public:\n"); if (classScope->needStaticInitializer()) { cg_printf("static void os_static_initializer();\n"); } if (variables->hasJumpTable(VariableTable::JumpTableClassStaticGetInit)) { cg_printf("static Variant os_getInit(CStrRef s);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_GETINIT_%s 1\n", clsName); } if (variables->hasJumpTable(VariableTable::JumpTableClassStaticGet)) { cg_printf("static Variant os_get(CStrRef s);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_GET_%s 1\n", clsName); } if (variables->hasJumpTable(VariableTable::JumpTableClassStaticLval)) { cg_printf("static Variant &os_lval(CStrRef s);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_LVAL_%s 1\n", clsName); } if (constants->hasJumpTable()) { cg_printf("static Variant os_constant(const char *s);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_CONSTANT_%s 1\n", clsName); } cg.printSection("DECLARE_INSTANCE_PROP_OPS"); cg_printf("public:\n"); if (classScope->hasGetClassPropTable()) { cg_printf("virtual const ClassPropTable *o_getClassPropTable() const;\n"); } if (variables->hasJumpTable(VariableTable::JumpTableClassRealProp)) { cg_printf("virtual Variant *o_realProp(CStrRef s, int flags,\n"); cg_printf(" CStrRef context = null_string) " "const;\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_%s 1\n", clsName); } if (variables->hasNonStaticPrivate()) { cg_printf("Variant *o_realPropPrivate(CStrRef s, int flags) const;\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_PRIVATE_%s 1\n", clsName); } cg.printSection("DECLARE_INSTANCE_PUBLIC_PROP_OPS"); cg_printf("public:\n"); if (variables->hasJumpTable(VariableTable::JumpTableClassRealPropPublic)) { cg_printf("virtual Variant *o_realPropPublic(CStrRef s, " "int flags) const;\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_PUBLIC_%s 1\n", clsName); } cg.printSection("DECLARE_COMMON_INVOKE"); cg.printf("static bool os_get_call_info(MethodCallPackage &mcp, " "int64 hash = -1);\n"); if (Option::UseMethodIndex) { cg.printf("virtual bool o_get_call_info_with_index(MethodCallPackage &mcp," " MethodIndex mi, int64 hash = -1);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_INVOKE_%s 1\n", clsName); } if (classScope->hasJumpTable(ClassScope::JumpTableInvoke)) { cg.printf("virtual bool o_get_call_info(MethodCallPackage &mcp, " "int64 hash = -1);\n"); } else { cg_printf("#define OMIT_JUMP_TABLE_CLASS_INVOKE_%s 1\n", clsName); } cg_printf("\n"); cg_printf("public:\n"); }