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