Пример #1
0
	LNSMul::LNSMul(Target * target, int wE, int wF) :
		Operator(target), wE(wE), wF(wF)
	{
		ostringstream name;
		/* The name has the format: LNSMul_wE_wF where: 
			wE = width of the integral part of the exponent
			wF = width of the fractional part of the exponent */
		name << "LNSMul_" << wE << "_" << wF; 
		setName(name.str());
		setCopyrightString("Jérémie Detrey, Florent de Dinechin (2003-2004), Sylvain Collange (2008)");
		addInput ("nA", wE + wF + 3);
		addInput ("nB", wE + wF + 3);
		addOutput("nR", wE + wF + 3);
		
		addConstant("wE", "positive", wE);
		addConstant("wF", "positive", wF);
		
		//vhdl << tab << declare("eRn", wE+wF+1) << " <= (nA(wE+wF-1) & nA(wE+wF-1 downto 0)) + (nB(wE+wF-1) & nB(wE+wF-1 downto 0));\n";

		IntAdder *my_adder = new IntAdder(target, wE+wF+1);
		oplist.push_back(my_adder);
		vhdl << tab << declare("X", wE+wF+1) << "<= nA(wE+wF-1) & nA(wE+wF-1 downto 0);\n";
		vhdl << tab << declare("Y", wE+wF+1) << "<= nB(wE+wF-1) & nB(wE+wF-1 downto 0);\n";
		inPortMap   (my_adder, "X", "X");
		inPortMap   (my_adder, "Y", "Y");
		inPortMapCst(my_adder, "Cin", "'0'");
		outPortMap (my_adder, "R","eRn");
		vhdl << instance(my_adder, "my_add");	
		
		vhdl << tab << declare("sRn") << " <= nA(wE+wF) xor nB(wE+wF);\n";
		vhdl << tab << declare("xRn", 2) << " <= \"00\" when eRn(wE+wF downto wE+wF-1) = \"10\" else\n"
			<< tab << "	 \"10\" when eRn(wE+wF downto wE+wF-1) = \"01\" else\n"
			<< tab << "	 \"01\";\n";
		vhdl << tab << declare("nRn", wE+wF+3) << " <= xRn & sRn & eRn(wE+wF-1 downto 0);\n";

		vhdl << tab << declare("xA", 2) << " <= nA(wE+wF+2 downto wE+wF+1);\n";
		vhdl << tab << declare("xB", 2) << " <= nB(wE+wF+2 downto wE+wF+1);\n";
		vhdl << tab << declare("xAB", 4) << " <= xA & xB when xA >= xB else\n"
			<< tab << "	 xB & xA;\n";
		vhdl
			<< tab << "with xAB select\n"
			<< tab << tab << "nR(wE+wF+2 downto wE+wF+1) <= xRn  when \"0101\",\n"
			<< tab << "	                                    \"00\" when \"0000\" | \"0100\",\n"
			<< tab << "	                                    \"10\" when \"1001\" | \"1010\",\n"
			<< tab << "	                                    \"11\" when others;\n"
			<< tab << "\n"
			<< tab << "nR(wE+wF downto 0) <= nRn(wE+wF downto 0);\n";
	}
Пример #2
0
unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
{
    unsigned numberOfConstants = numberOfConstantRegisters();
    for (unsigned i = 0; i < numberOfConstants; ++i) {
        if (getConstant(FirstConstantRegisterIndex + i) == v)
            return i;
    }
    return addConstant(v);
}
Пример #3
0
  static std::shared_ptr<SymbolTable> getPredefinedTable()
  {
    auto table = std::make_shared<SymbolTable>(nullptr, cs6300::GLOBAL);
    table->addType(std::string("integer"), BuiltInType::getInt());
    table->addType(std::string("INTEGER"), BuiltInType::getInt());
    table->addType(std::string("boolean"), BuiltInType::getBool());
    table->addType(std::string("BOOLEAN"), BuiltInType::getBool());
    table->addType(std::string("char"), BuiltInType::getChar());
    table->addType(std::string("CHAR"), BuiltInType::getChar());
    table->addType(std::string("string"), BuiltInType::getStr());
    table->addType(std::string("STRING"), BuiltInType::getStr());

    table->addConstant("true", std::make_shared<LiteralExpression>(true));
    table->addConstant("TRUE", std::make_shared<LiteralExpression>(true));
    table->addConstant("false", std::make_shared<LiteralExpression>(false));
    table->addConstant("FALSE", std::make_shared<LiteralExpression>(false));
    return table;
  }
Пример #4
0
// Add a constant polynomial
void Ctxt::addConstant(const ZZ& c)
{
  DoubleCRT dcrt(getContext(), getPrimeSet());
  long cc = rem(c, ptxtSpace); // reduce modulo plaintext space
  dcrt = cc;

  if (cc > ptxtSpace/2) cc -= ptxtSpace;
  double size = to_double(cc);

  addConstant(dcrt, size*size);
}
Пример #5
0
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& i : cls.interfaceNames)   pce->addInterface(i);
  for (auto& ut : cls.usedTraitNames)  pce->addUsedTrait(ut);
  for (auto& req : cls.traitRequirements) pce->addTraitRequirement(req);
  for (auto& tp : cls.traitPrecRules)  pce->addTraitPrecRule(tp);
  for (auto& ta : cls.traitAliasRules) pce->addTraitAliasRule(ta);

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  for (auto& prop : cls.properties) {
    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      KindOfInvalid // hphpcType
    );
  }

  for (auto& cconst : cls.constants) {
    pce->addConstant(
      cconst.name,
      cconst.typeConstraint,
      &cconst.val,
      cconst.phpCode
    );
  }
}
Пример #6
0
ParseStatus Parser::evalLiteral() {
  Token base = lex[0];

  switch(base.type) {
    case TT_KEYWORD:
      // put 'true' or 'false' on stack.
      return PARSE_OK;

    case TT_NATIVE:
      // put type on stack.
      return PARSE_OK;

    case TT_IDENTIFIER:
      // look up identifier & put on stack.
      return PARSE_OK;

    case TT_INTEGER:
      stack.push(Atom::value(base.s64));
      break;
    case TT_FLOAT:
      stack.push(Atom::value(base.f64));
      break;
    case TT_RUNE:
    case TT_STRING:
      stack.push(Atom::value(base.text));
      break;

    case TT_EOF:
    case TT_INVALID:
    case TT_OPERATOR:
    case TT_DELIMITER:
    case TT_DIRECTIVE:
    case TT_COMMENT:
    default:
      assert(false);
      return PARSE_ERROR;
  };

  // Literal is on the stack. Emit the code that puts it there.
  Atom& value = stack.back();
  int cslot = addConstant(value);
  emit(OC_LOADC, stack.size() - 1, cslot);

  return PARSE_OK;
}
Пример #7
0
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);
  pce->setNumDeclMethods(cls.numDeclMethods);

  pce->setIfaceVtableSlot(state.index.lookup_iface_vtable_slot(&cls));

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const makeRat = [&] (const Type& ty) -> RepoAuthType {
      if (ty.couldBe(TCls)) {
        return RepoAuthType{};
      }
      auto const rat = make_repo_type(*state.index.array_table_builder(), ty);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    auto const privPropTy = [&] (const PropState& ps) -> Type {
      /*
       * Skip closures, because the types of their used vars can be
       * communicated via assert opcodes right now.  At the time of this
       * writing there was nothing to gain by including RAT's for the
       * properties, since closure properties are only used internally by the
       * runtime, not directly via opcodes like CGetM.
       */
      if (is_closure(cls)) return Type{};

      auto it = ps.find(prop.name);
      if (it == end(ps)) return Type{};
      return it->second;
    };

    Type propTy;
    auto const attrs = prop.attrs;
    if (attrs & AttrPrivate) {
      propTy = privPropTy((attrs & AttrStatic) ? privateStatics : privateProps);
    } else if ((attrs & AttrPublic) && (attrs & AttrStatic)) {
      propTy = state.index.lookup_public_static(&cls, prop.name);
    }

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      makeRat(propTy)
    );
  }

  for (auto& cconst : cls.constants) {
    if (!cconst.val.hasValue()) {
      pce->addAbstractConstant(
        cconst.name,
        cconst.typeConstraint,
        cconst.isTypeconst
      );
    } else {
      pce->addConstant(
        cconst.name,
        cconst.typeConstraint,
        &cconst.val.value(),
        cconst.phpCode,
        cconst.isTypeconst
      );
    }
  }

  pce->setEnumBaseTy(cls.enumBaseTy);
}
Пример #8
0
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);
  pce->setNumDeclMethods(cls.numDeclMethods);

  pce->setIfaceVtableSlot(state.index.lookup_iface_vtable_slot(&cls));

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  std::vector<Type> useVars;
  if (is_closure(cls)) {
    auto f = find_method(&cls, s_invoke.get());
    useVars = state.index.lookup_closure_use_vars(f);
  }
  auto uvIt = useVars.begin();

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const makeRat = [&] (const Type& ty) -> RepoAuthType {
      if (ty.couldBe(TCls)) {
        return RepoAuthType{};
      }
      auto const rat = make_repo_type(*state.index.array_table_builder(), ty);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    auto const privPropTy = [&] (const PropState& ps) -> Type {
      if (is_closure(cls)) {
        // For closures use variables will be the first properties of the
        // closure object, in declaration order
        if (uvIt != useVars.end()) return *uvIt++;
        return Type{};
      }

      auto it = ps.find(prop.name);
      if (it == end(ps)) return Type{};
      return it->second;
    };

    Type propTy;
    auto const attrs = prop.attrs;
    if (attrs & AttrPrivate) {
      propTy = privPropTy((attrs & AttrStatic) ? privateStatics : privateProps);
    } else if ((attrs & AttrPublic) && (attrs & AttrStatic)) {
      propTy = state.index.lookup_public_static(&cls, prop.name);
    }

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      makeRat(propTy)
    );
  }
  assert(uvIt == useVars.end());

  for (auto& cconst : cls.constants) {
    if (!cconst.val.hasValue()) {
      pce->addAbstractConstant(
        cconst.name,
        cconst.typeConstraint,
        cconst.isTypeconst
      );
    } else {
      pce->addConstant(
        cconst.name,
        cconst.typeConstraint,
        &cconst.val.value(),
        cconst.phpCode,
        cconst.isTypeconst
      );
    }
  }

  pce->setEnumBaseTy(cls.enumBaseTy);
}
Пример #9
0
void primeSymbolTable(unsigned long symbolTableSize)
{
  int32_t trueValue   = -1;
  int32_t falseValue  =  0;
  int32_t maxintValue = MAXINT;
  STYPE *typePtr;
  register int16_t i;

  TRACE(lstFile,"[primeSymbolTable]");

  /* Allocate and initialize symbol table */

  symbolTable = malloc(symbolTableSize * sizeof(STYPE));
  if (!symbolTable)
    {
      fatal(eNOMEMORY);
    }

  nsym = 0;

  /* Add the standard constants to the symbol table */

  (void)addConstant("TRUE",   tBOOLEAN_CONST, &trueValue,   NULL);
  (void)addConstant("FALSE",  tBOOLEAN_CONST, &falseValue,  NULL);
  (void)addConstant("MAXINT", tINT_CONST,     &maxintValue, NULL);
  (void)addConstant("NIL",    tNIL,           &falseValue,  NULL);

  /* Add the standard types to the symbol table */

  typePtr = addTypeDefine("INTEGER", sINT, sINT_SIZE, NULL);
  if (typePtr)
    {
      parentInteger             = typePtr;
      typePtr->sParm.t.minValue = MININT;
      typePtr->sParm.t.maxValue = MAXINT;
    } /* end if */

  typePtr = addTypeDefine("BOOLEAN", sBOOLEAN, sBOOLEAN_SIZE, NULL);
  if (typePtr)
    {
      typePtr->sParm.t.minValue = falseValue;
      typePtr->sParm.t.maxValue = trueValue;
    } /* end if */

  typePtr = addTypeDefine("REAL", sREAL, sREAL_SIZE, NULL);

  typePtr = addTypeDefine("CHAR", sCHAR, sCHAR_SIZE, NULL);
  if (typePtr)
    {
      typePtr->sParm.t.minValue = MINCHAR;
      typePtr->sParm.t.maxValue = MAXCHAR;
    } /* end if */

  typePtr = addTypeDefine("TEXT", sFILE_OF, sCHAR_SIZE, NULL);
  if (typePtr)
    {
      typePtr->sParm.t.subType  = sCHAR;
      typePtr->sParm.t.minValue = MINCHAR;
      typePtr->sParm.t.maxValue = MAXCHAR;
    } /* end if */

  /* Add some enhanced Pascal standard" types to the symbol table
   *
   * string is represent by a 256 byte memory regions consisting of
   * one byte for the valid string length plus 255 bytes for string
   * storage
   */

  typePtr = addTypeDefine("STRING", sSTRING, sSTRING_SIZE, NULL);
  if (typePtr)
    {
      parentString              = typePtr;
      typePtr->sParm.t.rtype    = sRSTRING;
      typePtr->sParm.t.subType  = sCHAR;
      typePtr->sParm.t.rsize    = sRSTRING_SIZE;
      typePtr->sParm.t.flags    = STYPE_VARSIZE;
      typePtr->sParm.t.minValue = MINCHAR;
      typePtr->sParm.t.maxValue = MAXCHAR;
    } /* end if */

  /* Add the standard files to the symbol table */

  (void)addFile("INPUT",   0);
  (void)addFile("OUTPUT",  0);

  /* Initialize files table */

  for (i = 0; i <= MAX_FILES; i++)
    {
      files [i].defined = 0;
      files [i].flevel  = 0;
      files [i].ftype   = 0;
      files [i].faddr   = 0;
      files [i].fsize   = 0;
    } /* end for */
} /* end primeSymbolTable */
Пример #10
0
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const repoTy = [&] (const PropState& ps) -> RepoAuthType {
      // TODO(#3599292): we don't currently infer closure use var types.
      if (is_closure(cls)) return RepoAuthType{};
      auto it = ps.find(prop.name);
      if (it == end(ps)) return RepoAuthType{};
      auto const rat = make_repo_type(*state.index.array_table_builder(),
                                      it->second);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      (prop.attrs & AttrStatic) ? repoTy(privateStatics) : repoTy(privateProps)
    );
  }

  for (auto& cconst : cls.constants) {
    pce->addConstant(
      cconst.name,
      cconst.typeConstraint,
      &cconst.val,
      cconst.phpCode
    );
  }
}
Пример #11
0
ParseStatus Parser::parseDecl() {
  Token& name = lex[0];
  Token& op1 = lex[1];
  lex += 2;

  assert(name.isIdentifier());
  assert(resolve(name.text).isNil());
  int slot = allocateVariable(name.text);
  Atom& local = stack[slot];
  local.name_ = name.text;

  // Resolve the type expression if present.
  // TODO(aappleby): Allow complex type expressions.
  if (op1.isOperator(OP_COLON))
  {
    Atom type = resolve(lex[0].text);
    assert(!type.isNil());
    local.type_ = type.name_;
    lex++;
    assert(lex[0].isOperator(OP_EQUALS));
    lex++;
  }

  // Evaluate the right hand side.
  evalExpression();
  skipExpected(TT_DELIMITER, DL_SEMICOLON);
  Atom& value = stack.back();

  // Local type is inferred from the expression.
  if (op1.isOperator(OP_DECLARE)) {
    local.type_ = value.type_;
  } else if (local.type_ != value.type_) {
      // Attempt to convert the item to the given type if necessary.
    if (local.type_ == "int32" && value.type_ == "int64") {
      value.type_ = "int32";
    } else if (local.type_ == "float32" && value.type_ == "float64") {
      value.type_ = "float32";
    } else {
      assert(false);
    }
  }

  if (value.isSymbol()) {
    // Move the expression value to the slot.
    local.setValue(value);
    emit(OC_MOVV, slot, stack.size() - 1);
    emit(OC_POP, 1);
  } else {
    // The result of the right-hand expression is a constant.
    // Store it in the constant table and emit a load instruction to place it
    // in the destination register.
    local.ptype_ = value.ptype_;
    local.value_.blob = value.value_.blob;
    value.setName(name.text);
    assert(local == value);
    int cslot = addConstant(value);
    emit(OC_LOADC, slot, cslot);
  }

  stack.pop();
  return PARSE_OK;
}