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());
}
Example #2
0
ClassScopeRawPtr ConstantTable::findBase(
  AnalysisResultConstPtr ar, const std::string &name,
  const std::vector<std::string> &bases) const {
  for (int i = bases.size(); i--; ) {
    ClassScopeRawPtr p = ar->findClass(bases[i]);
    if (!p || p->isRedeclaring()) continue;
    if (p->hasConst(name)) return p;
    ConstantTablePtr constants = p->getConstants();
    p = constants->findBase(ar, name, p->getBases());
    if (p) return p;
  }
  return ClassScopeRawPtr();
}
Example #3
0
TypePtr ConstantTable::check(BlockScopeRawPtr context,
                             const std::string &name, TypePtr type,
                             bool coerce, AnalysisResultConstPtr ar,
                             ConstructPtr construct,
                             const std::vector<std::string> &bases,
                             BlockScope *&defScope) {
  ASSERT(!m_blockScope.is(BlockScope::FunctionScope));
  bool isClassScope = m_blockScope.is(BlockScope::ClassScope);
  TypePtr actualType;
  defScope = NULL;
  if (name == "true" || name == "false") {
    actualType = Type::Boolean;
  } else {
    Symbol *sym = getSymbol(name);
    if (!sym) {
      if (ar->getPhase() != AnalysisResult::AnalyzeInclude) {
        if (isClassScope) {
          ClassScopeRawPtr parent = findBase(ar, name, bases);
          if (parent) {
            actualType = parent->getConstants()->check(
              context, name, type, coerce, ar, construct, bases, defScope);
            if (defScope) return actualType;
          }
        }
        Compiler::Error(Compiler::UseUndeclaredConstant, construct);
        actualType = isClassScope ? Type::Variant : Type::String;
      }
    } else {
      ASSERT(sym->isPresent());
      ASSERT(sym->getType());
      ASSERT(sym->isConstant());
      defScope = &m_blockScope;
      if (isClassScope) {
        // if the current scope is a function scope, grab the lock.
        // otherwise if it's a class scope, then *try* to grab the lock.
        if (context->is(BlockScope::FunctionScope)) {
          GET_LOCK(BlockScopeRawPtr(&m_blockScope));
          return setType(ar, sym, type, coerce);
        } else {
          TRY_LOCK(BlockScopeRawPtr(&m_blockScope));
          return setType(ar, sym, type, coerce);
        }
      } else {
        Lock lock(m_blockScope.getMutex());
        return setType(ar, sym, type, coerce);
      }
    }
  }

  return actualType;
}
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();
  if (variables->hasAllJumpTables() && constants->hasJumpTable() &&
      classScope->hasAllJumpTables()) {
    cg_printf("DECLARE_CLASS(%s, %s, %s)\n", 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)\n", clsName, originalName);
  cg_printf("DECLARE_INVOKE_EX%s(%s, %s, %s)\n",
      Option::UseMethodIndex ? "WITH_INDEX" : "", clsName, originalName,
      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 (variables->hasJumpTable(VariableTable::JumpTableClassGetArray)) {
    cg_printf("virtual void o_getArray(Array &props) const;\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_GETARRAY_%s 1\n", clsName);
  }
  if (variables->hasJumpTable(VariableTable::JumpTableClassSetArray)) {
    cg_printf("virtual void o_setArray(CArrRef props);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_SETARRAY_%s 1\n", clsName);
  }

  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");
}