PageRenderTime 1004ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/model/TypeDef.cc

https://code.google.com/p/crack-language/
C++ | 1364 lines | 994 code | 189 blank | 181 comment | 196 complexity | 66131ce25a7eff4a5c2422eba001f074 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0, LGPL-3.0, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. // Copyright 2009-2012 Google Inc.
  2. // Copyright 2010-2012 Shannon Weyrick <weyrick@mozek.us>
  3. //
  4. // This Source Code Form is subject to the terms of the Mozilla Public
  5. // License, v. 2.0. If a copy of the MPL was not distributed with this
  6. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. //
  8. #include "TypeDef.h"
  9. #include <spug/check.h>
  10. #include <spug/Exception.h>
  11. #include <spug/StringFmt.h>
  12. #include "builder/Builder.h"
  13. #include "parser/Parser.h"
  14. #include "parser/Toker.h"
  15. #include "AllocExpr.h"
  16. #include "AssignExpr.h"
  17. #include "CleanupFrame.h"
  18. #include "Deserializer.h"
  19. #include "ArgDef.h"
  20. #include "Branchpoint.h"
  21. #include "Context.h"
  22. #include "FuncDef.h"
  23. #include "Generic.h"
  24. #include "GlobalNamespace.h"
  25. #include "Initializers.h"
  26. #include "InstVarDef.h"
  27. #include "OverloadDef.h"
  28. #include "ModuleDef.h"
  29. #include "ModuleStub.h"
  30. #include "NestedDeserializer.h"
  31. #include "NullConst.h"
  32. #include "ProtoBuf.h"
  33. #include "ResultExpr.h"
  34. #include "Serializer.h"
  35. #include "VarDef.h"
  36. #include "VarDefImpl.h"
  37. #include "VarRef.h"
  38. using namespace builder;
  39. using namespace std;
  40. using namespace model;
  41. using namespace spug;
  42. using namespace parser;
  43. // returns true if func is non-null and abstract
  44. bool TypeDef::isAbstract(FuncDef *func) {
  45. if (func && (func->flags & FuncDef::abstract)) {
  46. // found one. do a look-up on the function, if there is a
  47. // non-abstract implementation we should get a match that is
  48. // _not_ abstract and has the same receiver type (to rule out the
  49. // possibility that the implementation is for a method with the same
  50. // signature in a different class).
  51. OverloadDefPtr overloads =
  52. OverloadDefPtr::rcast(lookUp(func->name));
  53. assert(overloads);
  54. FuncDefPtr nearest = overloads->getSigMatch(func->args);
  55. if (nearest->flags & FuncDef::abstract ||
  56. func->receiverType != nearest->receiverType
  57. )
  58. return true;
  59. }
  60. return false;
  61. }
  62. // if overload contains abstract functions, returns true and adds them to
  63. // abstractFuncs (assuming abstractFuncs is non-null)
  64. bool TypeDef::hasAbstractFuncs(OverloadDef *overload,
  65. vector<FuncDefPtr> *abstractFuncs
  66. ) {
  67. bool gotAbstract = false;
  68. for (OverloadDef::FuncList::iterator iter = overload->beginTopFuncs();
  69. iter != overload->endTopFuncs();
  70. ++iter
  71. ) {
  72. if (isAbstract(iter->get()))
  73. if (abstractFuncs) {
  74. abstractFuncs->push_back(iter->get());
  75. gotAbstract = true;
  76. } else {
  77. return true;
  78. }
  79. }
  80. return gotAbstract;
  81. }
  82. TypeDef *TypeDef::findSpecialization(TypeVecObj *types) {
  83. assert(generic && "find specialization called on non-generic type");
  84. SpecializationCache::iterator match = generic->find(types);
  85. if (match != generic->end() && match->first.equals(types))
  86. return match->second.get();
  87. else
  88. return 0;
  89. }
  90. void TypeDef::storeDef(VarDef *def) {
  91. Namespace::storeDef(def);
  92. if (def->hasInstSlot())
  93. ordered.push_back(def);
  94. }
  95. TypeDef *TypeDef::extractInstantiation(ModuleDef *module, TypeVecObj *types) {
  96. TypeDefPtr result = module->getType(name);
  97. SPUG_CHECK(result,
  98. "Instantiated generic " << module->getNamespaceName() <<
  99. " not defined in its module."
  100. );
  101. result->genericParms = *types;
  102. result->templateType = this;
  103. (*generic)[types] = result;
  104. return result.get();
  105. }
  106. ModuleDefPtr TypeDef::getModule() {
  107. return owner->getModule();
  108. }
  109. bool TypeDef::isHiddenScope() {
  110. return owner->isHiddenScope();
  111. }
  112. VarDef *TypeDef::asVarDef() {
  113. return this;
  114. }
  115. NamespacePtr TypeDef::getParent(unsigned i) {
  116. if (i < parents.size())
  117. return parents[i];
  118. else
  119. return 0;
  120. }
  121. NamespacePtr TypeDef::getNamespaceOwner() {
  122. return getOwner();
  123. }
  124. bool TypeDef::hasGenerics() const {
  125. return genericInfo || Namespace::hasGenerics();
  126. }
  127. void TypeDef::addDefToMeta(OverloadDef *def) {
  128. // As long as this not not the "Class" class, add the overload to it.
  129. // We have to verify 'type' is non-null for generics.
  130. if (type && type.get() != this)
  131. type->addAlias(def);
  132. }
  133. bool TypeDef::hasInstSlot() {
  134. return false;
  135. }
  136. bool TypeDef::isImplicitFinal(const std::string &name) {
  137. return name == "oper init" ||
  138. name == "oper bind" ||
  139. name == "oper release";
  140. }
  141. void TypeDef::addToAncestors(Context &context, TypeVec &ancestors) {
  142. // ignore VTableBase
  143. if (this == context.construct->vtableBaseType)
  144. return;
  145. // make sure this isn't a primitive class (we use the "pointer" attribute
  146. // to make this determination)
  147. if (!pointer)
  148. context.error(SPUG_FSTR("You may not inherit from " <<
  149. getDisplayName() <<
  150. " because it's a primitive class."
  151. )
  152. );
  153. // store the current endpoint so we don't bother checking against our own
  154. // ancestors.
  155. size_t initAncSize = ancestors.size();
  156. // if this is the object class, make sure that it's the first ancestor.
  157. if (initAncSize && this == context.construct->objectType)
  158. context.error("If you directly or indirectly inherit from Object, "
  159. "Object (or its derivative) must come first in the "
  160. "ancestor list.");
  161. for (TypeVec::const_iterator iter = parents.begin();
  162. iter != parents.end();
  163. ++iter
  164. )
  165. (*iter)->addToAncestors(context, ancestors);
  166. // make sure that we're not already in the ancestor list
  167. for (size_t i = 0; i < initAncSize; ++i)
  168. if (ancestors[i] == this)
  169. context.error(SPUG_FSTR("Class " << getDisplayName() <<
  170. " is already an ancestor."
  171. )
  172. );
  173. // add this to the ancestors.
  174. ancestors.push_back(this);
  175. }
  176. bool TypeDef::isDerivedFrom(const TypeDef *other) const {
  177. if (this == other)
  178. return true;
  179. for (TypeVec::const_iterator iter = parents.begin();
  180. iter != parents.end();
  181. ++iter
  182. )
  183. if ((*iter)->isDerivedFrom(other))
  184. return true;
  185. return false;
  186. }
  187. VarDefPtr TypeDef::emitVarDef(Context &container, const std::string &name,
  188. Expr *initializer
  189. ) {
  190. return container.builder.emitVarDef(container, this, name, initializer);
  191. }
  192. bool TypeDef::matches(const TypeDef &other) const {
  193. if (&other == this)
  194. return true;
  195. // try the parents
  196. for (TypeVec::const_iterator iter = other.parents.begin();
  197. iter != other.parents.end();
  198. ++iter
  199. )
  200. if (matches(**iter))
  201. return true;
  202. return false;
  203. }
  204. FuncDefPtr TypeDef::createOperInit(Context &classContext,
  205. const ArgVec &args
  206. ) {
  207. assert(classContext.ns.get() == this); // needed for final addDef()
  208. ContextPtr funcContext = classContext.createSubContext(Context::local);
  209. funcContext->toplevel = true;
  210. // create the "this" variable
  211. ArgDefPtr thisDef = classContext.builder.createArgDef(this, "this");
  212. funcContext->addDef(thisDef.get());
  213. VarRefPtr thisRef = new VarRef(thisDef.get());
  214. TypeDef *voidType = classContext.construct->voidType.get();
  215. FuncDefPtr newFunc = classContext.builder.emitBeginFunc(*funcContext,
  216. FuncDef::method,
  217. "oper init",
  218. voidType,
  219. args,
  220. 0
  221. );
  222. // do initialization for the base classes.
  223. for (TypeVec::iterator ibase = parents.begin(); ibase != parents.end();
  224. ++ibase
  225. ) {
  226. // if the base class contains no constructors at all, either it's a
  227. // special class or it has no need for constructors, so ignore it.
  228. OverloadDefPtr overloads = (*ibase)->lookUp("oper init");
  229. if (!overloads)
  230. continue;
  231. // look for a matching constructor
  232. bool useDefaultCons = false;
  233. FuncDefPtr baseInit = overloads->getSigMatch(args, true);
  234. if (!baseInit || baseInit->getOwner() != ibase->get()) {
  235. // we must get a default initializer and it must be specific to the
  236. // base class (not inherited from an ancestor of the base class)
  237. useDefaultCons = true;
  238. baseInit = overloads->getNoArgMatch(false);
  239. if (!baseInit || baseInit->getOwner() != ibase->get())
  240. classContext.error(SPUG_FSTR("Cannot create a default "
  241. "constructor because base "
  242. "class " <<
  243. (*ibase)->name <<
  244. " has no default constructor."
  245. )
  246. );
  247. }
  248. FuncCallPtr funcCall =
  249. classContext.builder.createFuncCall(baseInit.get());
  250. funcCall->receiver = thisRef;
  251. // construct an argument list if we're not using the default arguments
  252. if (!useDefaultCons && args.size()) {
  253. for (int i = 0; i < args.size(); ++i)
  254. funcCall->args.push_back(
  255. funcContext->builder.createVarRef(args[i].get())
  256. );
  257. }
  258. funcCall->emit(*funcContext);
  259. }
  260. // generate constructors for all of the instance variables in the order
  261. // that they were declared.
  262. for (VarDefVec::iterator iter = beginOrderedDefs();
  263. iter != endOrderedDefs();
  264. ++iter
  265. ) {
  266. InstVarDef *ivar = InstVarDefPtr::arcast(*iter);
  267. // when creating a default constructor, everything has to have an
  268. // initializer.
  269. // XXX make this a parser error
  270. if (!ivar->initializer)
  271. classContext.error(SPUG_FSTR("no initializer for variable " <<
  272. ivar->name <<
  273. " while creating default "
  274. "constructor."
  275. )
  276. );
  277. AssignExprPtr assign = new AssignExpr(thisRef.get(),
  278. ivar,
  279. ivar->initializer.get()
  280. );
  281. classContext.builder.emitFieldAssign(*funcContext, thisRef.get(),
  282. assign.get()
  283. );
  284. }
  285. classContext.builder.emitReturn(*funcContext, 0);
  286. classContext.builder.emitEndFunc(*funcContext, newFunc.get());
  287. classContext.addDef(newFunc.get());
  288. return newFunc;
  289. }
  290. FuncDefPtr TypeDef::createDefaultInit(Context &classContext) {
  291. ArgVec args(0);
  292. return createOperInit(classContext, args);
  293. }
  294. void TypeDef::createDefaultDestructor(Context &classContext) {
  295. assert(classContext.ns.get() == this); // needed for final addDef()
  296. ContextPtr funcContext = classContext.createSubContext(Context::local);
  297. funcContext->toplevel = true;
  298. // create the "this" variable
  299. ArgDefPtr thisDef = classContext.builder.createArgDef(this, "this");
  300. funcContext->addDef(thisDef.get());
  301. FuncDef::Flags flags =
  302. FuncDef::method |
  303. (hasVTable ? FuncDef::virtualized : FuncDef::noFlags);
  304. // check for an override
  305. FuncDefPtr override = classContext.lookUpNoArgs("oper del", true, this);
  306. ArgVec args(0);
  307. TypeDef *voidType = classContext.construct->voidType.get();
  308. FuncDefPtr delFunc = classContext.builder.emitBeginFunc(*funcContext,
  309. flags,
  310. "oper del",
  311. voidType,
  312. args,
  313. override.get()
  314. );
  315. // all we have to do is add the destructor cleanups
  316. addDestructorCleanups(*funcContext);
  317. // ... and close off the function
  318. classContext.builder.emitReturn(*funcContext, 0);
  319. classContext.builder.emitEndFunc(*funcContext, delFunc.get());
  320. classContext.addDef(delFunc.get());
  321. }
  322. void TypeDef::createNewFunc(Context &classContext, FuncDef *initFunc) {
  323. ContextPtr funcContext = classContext.createSubContext(Context::local);
  324. funcContext->toplevel = true;
  325. funcContext->returnType = this;
  326. // copy the original arg list
  327. ArgVec args;
  328. for (ArgVec::iterator iter = initFunc->args.begin();
  329. iter != initFunc->args.end();
  330. ++iter
  331. ) {
  332. ArgDefPtr argDef =
  333. classContext.builder.createArgDef((*iter)->type.get(),
  334. (*iter)->name
  335. );
  336. args.push_back(argDef);
  337. funcContext->addDef(argDef.get());
  338. }
  339. FuncDefPtr newFunc = classContext.builder.emitBeginFunc(*funcContext,
  340. FuncDef::noFlags,
  341. "oper new",
  342. this,
  343. args,
  344. 0
  345. );
  346. // create "Type this = alloc(Type);"
  347. ExprPtr allocExpr = new AllocExpr(this);
  348. VarDefPtr thisVar = classContext.builder.emitVarDef(*funcContext, this,
  349. "this",
  350. allocExpr.get(),
  351. false
  352. );
  353. VarRefPtr thisRef = new VarRef(thisVar.get());
  354. // initialize all vtable_base pointers. XXX hack. Replace this with code
  355. // in vtable_base.oper init() once we get proper constructor composition
  356. if (hasVTable) {
  357. thisRef->emit(*funcContext);
  358. classContext.builder.emitVTableInit(*funcContext, this);
  359. }
  360. // create "this.init(*args);"
  361. FuncCallPtr initFuncCall = new FuncCall(initFunc);
  362. FuncCall::ExprVec initArgs(args.size());
  363. for (ArgVec::iterator iter = args.begin(); iter != args.end();
  364. ++iter
  365. )
  366. initFuncCall->args.push_back(new VarRef(iter->get()));
  367. initFuncCall->receiver = thisRef;
  368. initFuncCall->emit(*funcContext);
  369. // return the resulting object and close the new function
  370. classContext.builder.emitReturn(*funcContext, thisRef.get());
  371. classContext.builder.emitEndFunc(*funcContext, newFunc.get());
  372. // register it in the class
  373. classContext.addDef(newFunc.get());
  374. }
  375. void TypeDef::createCast(Context &outer, bool throws) {
  376. assert(hasVTable && "Attempt to createCast() on a non-virtual class");
  377. ContextPtr funcCtx = outer.createSubContext(Context::local);
  378. funcCtx->toplevel = true;
  379. funcCtx->returnType = this;
  380. ArgVec args;
  381. args.reserve(2);
  382. args.push_back(
  383. outer.builder.createArgDef(outer.construct->vtableBaseType.get(),
  384. "val"
  385. )
  386. );
  387. // if this isn't the throwing variety, add a "defaultValue" arg.
  388. if (!throws)
  389. args.push_back(
  390. outer.builder.createArgDef(this, "defaultValue")
  391. );
  392. FuncDefPtr castFunc = outer.builder.emitBeginFunc(*funcCtx,
  393. FuncDef::noFlags,
  394. "cast",
  395. this,
  396. args,
  397. 0
  398. );
  399. // function body is:
  400. // if (val.class.isSubclass(ThisClass);
  401. // return ThisClass.unsafeCast(val);
  402. // else
  403. // __CrackBadCast(val.class, ThisClass);
  404. // val.class
  405. VarRefPtr valRef = funcCtx->builder.createVarRef(args[0].get());
  406. FuncDefPtr f = funcCtx->lookUpNoArgs("oper class", false);
  407. assert(f && "oper class missing");
  408. // XXX this was trace code that mysteriously seg-faults: since I think there
  409. // might be some memory corruption happening, I'm leaving this until I can
  410. // investigate.
  411. // string s = f->receiverType->name;
  412. // std::cerr << "Got oper class for " << s << endl;
  413. FuncCallPtr call = funcCtx->builder.createFuncCall(f.get());
  414. call->receiver = valRef;
  415. ExprPtr valClass = call;
  416. valClass = valClass->emit(*funcCtx);
  417. // $.isSubclass(ThisClass)
  418. FuncCall::ExprVec isSubclassArgs(1);
  419. isSubclassArgs[0] = funcCtx->builder.createVarRef(this);
  420. f = funcCtx->lookUp("isSubclass", isSubclassArgs, type.get());
  421. assert(f && "isSubclass missing");
  422. call = funcCtx->builder.createFuncCall(f.get());
  423. call->args = isSubclassArgs;
  424. call->receiver = valClass;
  425. // if ($)
  426. BranchpointPtr branchpoint = funcCtx->builder.emitIf(*funcCtx, call.get());
  427. // return ThisClass.unsafeCast(val);
  428. FuncCall::ExprVec unsafeCastArgs(1);
  429. unsafeCastArgs[0] = valRef;
  430. f = funcCtx->lookUp("unsafeCast", unsafeCastArgs, type.get());
  431. assert(f && "unsafeCast missing");
  432. call = funcCtx->builder.createFuncCall(f.get());
  433. call->args = unsafeCastArgs;
  434. funcCtx->builder.emitReturn(*funcCtx, call.get());
  435. // else
  436. branchpoint = funcCtx->builder.emitElse(*funcCtx, branchpoint.get(), true);
  437. if (throws) {
  438. // __CrackBadCast(val.class, ThisClass);
  439. FuncCall::ExprVec badCastArgs(2);
  440. badCastArgs[0] = valClass;
  441. badCastArgs[1] = funcCtx->builder.createVarRef(this);
  442. f = outer.getParent()->lookUp("__CrackBadCast", badCastArgs);
  443. assert(f && "__CrackBadCast missing");
  444. call = funcCtx->builder.createFuncCall(f.get());
  445. call->args = badCastArgs;
  446. funcCtx->createCleanupFrame();
  447. call->emit(*funcCtx)->handleTransient(*funcCtx);
  448. funcCtx->closeCleanupFrame();
  449. // need to "return null" to provide a terminator.
  450. TypeDef *vp = outer.construct->voidptrType.get();
  451. ExprPtr nullVal = (new NullConst(vp))->convert(*funcCtx, this);
  452. funcCtx->builder.emitReturn(*funcCtx, nullVal.get());
  453. } else {
  454. // return defaultVal;
  455. VarRefPtr defaultValRef = funcCtx->builder.createVarRef(args[1].get());
  456. funcCtx->builder.emitReturn(*funcCtx, defaultValRef.get());
  457. }
  458. // end of story.
  459. funcCtx->builder.emitEndIf(*funcCtx, branchpoint.get(), true);
  460. funcCtx->builder.emitEndFunc(*funcCtx, castFunc.get());
  461. // add the cast function to the meta-class
  462. outer.addDef(castFunc.get(), type.get());
  463. }
  464. bool TypeDef::gotAbstractFuncs(vector<FuncDefPtr> *abstractFuncs,
  465. TypeDef *ancestor
  466. ) {
  467. bool gotAbstract = false;
  468. if (!ancestor)
  469. ancestor = this;
  470. // iterate over the definitions, locate all abstract functions
  471. for (VarDefMap::iterator iter = ancestor->beginDefs();
  472. iter != ancestor->endDefs();
  473. ++iter
  474. ) {
  475. OverloadDef *ovld = OverloadDefPtr::rcast(iter->second);
  476. if (ovld && hasAbstractFuncs(ovld, abstractFuncs)) {
  477. if (abstractFuncs)
  478. gotAbstract = true;
  479. else
  480. return true;
  481. }
  482. }
  483. // recurse through all of the parents
  484. TypeDefPtr parent;
  485. for (int i = 0; parent = ancestor->getParent(i++);)
  486. if (gotAbstractFuncs(abstractFuncs, parent.get()))
  487. if (abstractFuncs)
  488. gotAbstract = true;
  489. else
  490. return true;
  491. return gotAbstract;
  492. }
  493. void TypeDef::aliasBaseMetaTypes() {
  494. for (TypeVec::iterator base = parents.begin();
  495. base != parents.end();
  496. ++base
  497. ) {
  498. TypeDef *meta = (*base)->type.get();
  499. assert(meta != base->get());
  500. for (VarDefMap::iterator var = meta->beginDefs();
  501. var != meta->endDefs();
  502. ++var
  503. ) {
  504. // add all overloads that we haven't already defined.
  505. // XXX this check is extremely lame. First of all, we should be
  506. // separating namespace qualification from attribute/method access
  507. // and we should probably do so explicitly. Secondly, if we were
  508. // going to continue in the current direction, what we need here
  509. // is to do our checking at the signature level for each function,
  510. // and allow Parser's addDef() to override existing values.
  511. if (OverloadDefPtr::rcast(var->second) &&
  512. !type->lookUp(var->first) &&
  513. var->first != "cast")
  514. type->addAlias(var->second.get());
  515. }
  516. }
  517. }
  518. void TypeDef::rectify(Context &classContext) {
  519. // if this is an abstract class, make sure we have abstract methods. If
  520. // it is not, make sure we don't have abstract methods.
  521. if (abstract && !gotAbstractFuncs()) {
  522. classContext.warn(SPUG_FSTR("Abstract class " << name <<
  523. " has no abstract functions."
  524. )
  525. );
  526. } else if (!abstract) {
  527. vector<FuncDefPtr> funcs;
  528. if (gotAbstractFuncs(&funcs)) {
  529. ostringstream tmp;
  530. tmp << "Non-abstract class " << name <<
  531. " has abstract methods:\n";
  532. for (int i = 0; i < funcs.size(); ++i)
  533. tmp << " " << *funcs[i] << '\n';
  534. classContext.error(tmp.str());
  535. }
  536. }
  537. // if there are no init functions specific to this class, create a
  538. // default constructor and possibly wrap it in a new function.
  539. if (!lookUp("oper init", false)) {
  540. FuncDefPtr initFunc = createDefaultInit(classContext);
  541. if (!abstract)
  542. createNewFunc(classContext, initFunc.get());
  543. }
  544. // if the class doesn't already define a delete operator specific to the
  545. // class, generate one.
  546. FuncDefPtr operDel = classContext.lookUpNoArgs("oper del");
  547. if (!operDel || operDel->getOwner() != this)
  548. createDefaultDestructor(classContext);
  549. }
  550. bool TypeDef::isParent(TypeDef *type) {
  551. for (TypeVec::iterator iter = parents.begin();
  552. iter != parents.end();
  553. ++iter
  554. )
  555. if (type == iter->get())
  556. return true;
  557. return false;
  558. }
  559. FuncDefPtr TypeDef::getConverter(Context &context, const TypeDef &other) {
  560. return context.lookUpNoArgs("oper to " + other.getFullName(), true, this);
  561. }
  562. bool TypeDef::getPathToAncestor(const TypeDef &ancestor,
  563. TypeDef::AncestorPath &path,
  564. unsigned depth
  565. ) {
  566. if (this == &ancestor) {
  567. path.resize(depth);
  568. return true;
  569. }
  570. int i = 0;
  571. for (TypeVec::iterator iter = parents.begin();
  572. iter != parents.end();
  573. ++iter, ++i
  574. ) {
  575. TypeDef *base = iter->get();
  576. if (base->getPathToAncestor(ancestor, path, depth + 1)) {
  577. path[depth].index = i;
  578. path[depth].ancestor = base;
  579. return true;
  580. }
  581. }
  582. return false;
  583. }
  584. void TypeDef::emitInitializers(Context &context, Initializers *inits) {
  585. VarDefPtr thisDef = context.ns->lookUp("this");
  586. assert(thisDef &&
  587. "trying to emit initializers in a context with no 'this'");
  588. VarRefPtr thisRef = new VarRef(thisDef.get());
  589. // do initialization for the base classes.
  590. for (TypeVec::iterator ibase = parents.begin(); ibase != parents.end();
  591. ++ibase
  592. ) {
  593. TypeDef *base = ibase->get();
  594. // see if there's a constructor for the base class in our list of
  595. // initializers.
  596. FuncCallPtr initCall = inits->getBaseInitializer(base);
  597. if (initCall) {
  598. initCall->emit(context);
  599. continue;
  600. }
  601. // if the base class contains no constructors at all, either it's a
  602. // special class or it has no need for constructors, so ignore it.
  603. OverloadDefPtr overloads = base->lookUp("oper init");
  604. if (!overloads)
  605. continue;
  606. // we must get a default initializer and it must be specific to the
  607. // base class (not inherited from an ancestor of the base class)
  608. ArgVec args;
  609. FuncDefPtr baseInit = overloads->getSigMatch(args);
  610. if (!baseInit || baseInit->getOwner() != base)
  611. context.error(SPUG_FSTR("Cannot initialize base classes "
  612. "because base class " <<
  613. base->name <<
  614. " has no default constructor."
  615. )
  616. );
  617. FuncCallPtr funcCall = context.builder.createFuncCall(baseInit.get());
  618. funcCall->receiver = thisRef;
  619. funcCall->emit(context);
  620. }
  621. // generate constructors for all of the instance variables
  622. for (VarDefVec::iterator iter = beginOrderedDefs();
  623. iter != endOrderedDefs();
  624. ++iter
  625. ) {
  626. InstVarDef *ivar = InstVarDefPtr::arcast(*iter);
  627. // see if the user has supplied an initializer, use it if so.
  628. ExprPtr initializer = inits->getFieldInitializer(ivar);
  629. if (!initializer)
  630. initializer = ivar->initializer;
  631. // when creating a default constructor, everything has to have an
  632. // initializer.
  633. // XXX make this a parser error
  634. if (!initializer)
  635. context.error(SPUG_FSTR("no initializer for variable " <<
  636. ivar->name <<
  637. " while creating default "
  638. "constructor."
  639. )
  640. );
  641. SPUG_CHECK(initializer->type->isDerivedFrom(ivar->type.get()),
  642. "initializer for " << ivar->name << " should be of type " <<
  643. ivar->type->getDisplayName() <<
  644. " but is of incompatible type " <<
  645. initializer->type->getDisplayName()
  646. );
  647. AssignExprPtr assign = new AssignExpr(thisRef.get(),
  648. ivar,
  649. initializer.get()
  650. );
  651. context.builder.emitFieldAssign(context, thisRef.get(),
  652. assign.get()
  653. );
  654. }
  655. initializersEmitted = true;
  656. }
  657. void TypeDef::addDestructorCleanups(Context &context) {
  658. VarRefPtr thisRef = new VarRef(context.ns->lookUp("this").get());
  659. // first add the cleanups for the base classes, in order defined, then the
  660. // cleanups for the derived classes. Cleanups are applied in the reverse
  661. // order that they are added, so this will result in the expected
  662. // destruction order of instance variables followed by base classes.
  663. // generate calls to the destructors for all of the base classes.
  664. for (TypeVec::iterator ibase = parents.begin();
  665. ibase != parents.end();
  666. ++ibase
  667. ) {
  668. TypeDef *base = ibase->get();
  669. // check for a delete operator (the primitive base classes don't have
  670. // them and don't need cleanup)
  671. FuncDefPtr operDel = context.lookUpNoArgs("oper del", true, base);
  672. if (!operDel)
  673. continue;
  674. // create a cleanup function and don't call it through the vtable.
  675. FuncCallPtr funcCall =
  676. context.builder.createFuncCall(operDel.get(), true);
  677. funcCall->receiver = thisRef.get();
  678. context.cleanupFrame->addCleanup(funcCall.get());
  679. }
  680. // generate destructors for all of the instance variables in order of
  681. // definition (cleanups run in the reverse order that they were added,
  682. // which is exactly what we want).
  683. for (VarDefVec::iterator iter = beginOrderedDefs();
  684. iter != endOrderedDefs();
  685. ++iter
  686. )
  687. context.cleanupFrame->addCleanup(iter->get(), thisRef.get());
  688. initializersEmitted = true;
  689. }
  690. string TypeDef::getSpecializedName(TypeVecObj *types, bool fullName) {
  691. // construct the module name from the class name plus type parameters
  692. ostringstream tmp;
  693. tmp << (fullName ? getFullName() : name) << '[';
  694. int last = types->size()-1;
  695. for (int i = 0; i <= last; ++i) {
  696. tmp << (*types)[i]->getFullName();
  697. if (i != last)
  698. tmp << ',';
  699. }
  700. tmp << ']';
  701. return tmp.str();
  702. }
  703. void instantiateGeneric(TypeDef *type, Context &context, Context &localCtx,
  704. TypeDef::TypeVecObj *types
  705. ) {
  706. // alias all global symbols in the original module. For the compile
  707. // namespace, just reuse that of the generic.
  708. localCtx.ns->aliasAll(type->genericInfo->ns.get());
  709. localCtx.compileNS = type->genericInfo->compileNS;
  710. // alias the template arguments to their parameter names
  711. for (int i = 0; i < types->size(); ++i)
  712. localCtx.ns->addAlias(type->genericInfo->parms[i]->name,
  713. (*types)[i].get()
  714. );
  715. istringstream fakeInput;
  716. Toker toker(fakeInput, "ignored-name");
  717. type->genericInfo->replay(toker);
  718. toker.putBack(Token(Token::ident, type->name, Location()));
  719. toker.putBack(Token(Token::classKw, "class", Location()));
  720. if (type->abstract)
  721. localCtx.nextClassFlags =
  722. static_cast<TypeDef::Flags>(model::TypeDef::explicitFlags |
  723. model::TypeDef::abstractClass
  724. );
  725. Location instantiationLoc = context.getLocation();
  726. if (instantiationLoc)
  727. localCtx.pushErrorContext(SPUG_FSTR("in generic instantiation "
  728. "at " << instantiationLoc
  729. )
  730. );
  731. else
  732. // XXX I think we should never get here now that we're
  733. // materializing generic modules.
  734. localCtx.pushErrorContext(SPUG_FSTR("In generic instantiation "
  735. "from compiled module "
  736. "(this should never "
  737. "happen!)"
  738. )
  739. );
  740. Parser parser(toker, &localCtx);
  741. parser.parse();
  742. localCtx.popErrorContext();
  743. }
  744. namespace {
  745. class DummyModuleDef : public ModuleDef {
  746. public:
  747. DummyModuleDef(const string &name, Namespace *ns) :
  748. ModuleDef(name, ns) {
  749. }
  750. virtual void callDestructor() {}
  751. virtual void runMain(builder::Builder &builder) {}
  752. virtual bool isHiddenScope() { return true; }
  753. };
  754. // Callback to replace a stubbed instantiation in the instantiation cache
  755. // when its module is replaced.
  756. struct FixStubbedInstantiation : public ModuleStub::Callback {
  757. TypeDef::TypeVecObjPtr parms;
  758. TypeDefPtr generic, instantiation;
  759. FixStubbedInstantiation(TypeDef *generic, TypeDef *instantiation,
  760. TypeDef::TypeVecObj *parms
  761. ) :
  762. parms(parms),
  763. generic(generic),
  764. instantiation(instantiation) {
  765. }
  766. virtual void run(Context &context) {
  767. TypeDef::SpecializationCache::iterator entry =
  768. generic->generic->find(parms.get());
  769. // make sure it hasn't already been replaced
  770. if (entry->second == instantiation)
  771. entry->second = instantiation->replaceStub(context);
  772. }
  773. };
  774. }
  775. TypeDefPtr TypeDef::getSpecialization(Context &context,
  776. TypeDef::TypeVecObj *types
  777. ) {
  778. assert(genericInfo);
  779. // check the type's specialization cache
  780. TypeDef *result = findSpecialization(types);
  781. if (result) {
  782. // record a dependency on the owner's module and return the result.
  783. context.recordDependency(result->getOwner()->getModule().get());
  784. return result;
  785. }
  786. // construct the module name from the class name plus type parameters
  787. string moduleName = getSpecializedName(types, true);
  788. string newTypeName = getSpecializedName(types, false);
  789. // the name that the specialization will be stored as in the
  790. // specialization module. This varies depending on whether we are
  791. // building the specialization or loading from the precompiled module cache.
  792. string nameInModule;
  793. // check the precompiled module cache
  794. ModuleDefPtr module = context.construct->getCachedModule(moduleName);
  795. if (!module) {
  796. // make sure we've got the right number of arguments
  797. if (types->size() != genericInfo->parms.size())
  798. context.error(SPUG_FSTR("incorrect number of arguments for "
  799. "generic " << moduleName <<
  800. ". Expected " <<
  801. genericInfo->parms.size() << " got " <<
  802. types->size()
  803. )
  804. );
  805. // if any of the parameters of the generic or the generic itself are
  806. // in a hidden scope, we don't want to create an ephemeral module for
  807. // it.
  808. bool hidden = false;
  809. if (isHidden()) {
  810. hidden = true;
  811. } else {
  812. for (int i = 0; i < types->size(); ++i) {
  813. if ((*types)[i]->isHidden()) {
  814. hidden = true;
  815. break;
  816. }
  817. }
  818. }
  819. if (hidden) {
  820. ModuleDefPtr dummyMod = new DummyModuleDef(moduleName,
  821. context.ns.get()
  822. );
  823. // create a dummy module in the current context.
  824. dummyMod->setOwner(
  825. genericInfo->getInstanceModuleOwner(context.isGeneric()).get()
  826. );
  827. ContextPtr instantiationContext =
  828. context.createSubContext(Context::module, dummyMod.get());
  829. instantiationContext->toplevel = true;
  830. instantiationContext->generic = true;
  831. instantiateGeneric(this, context, *instantiationContext, types);
  832. return extractInstantiation(dummyMod.get(), types);
  833. }
  834. // create an ephemeral module for the new class
  835. Context *rootContext = context.construct->rootContext.get();
  836. NamespacePtr compileNS =
  837. new GlobalNamespace(rootContext->compileNS.get(),
  838. moduleName
  839. );
  840. BuilderPtr moduleBuilder =
  841. context.construct->rootBuilder->createChildBuilder();
  842. ContextPtr modContext =
  843. new Context(*moduleBuilder, Context::module, rootContext,
  844. new GlobalNamespace(rootContext->ns.get(),
  845. moduleName
  846. )
  847. );
  848. modContext->toplevel = true;
  849. modContext->generic = true;
  850. // create the new module with the current module as the owner. Use
  851. // the newTypeName instead of moduleName, since this is how we should
  852. // have done it for modules in the first place and we're going to
  853. // override the canonical name later anyway.
  854. ModuleDefPtr currentModule = context.ns->getModule();
  855. if (!currentModule)
  856. cout << "no current module for " << newTypeName << endl;
  857. module = modContext->createModule(newTypeName, "", currentModule.get());
  858. // XXX this is confusing: there's a "owner" that's part of some kinds of
  859. // ModuleDef that's different from VarDef::owner - we set VarDef::owner
  860. // here so that we can accept protected variables from the original
  861. // module's context
  862. ModuleDefPtr owner = genericInfo->ns->getRealModule();
  863. module->setOwner(
  864. genericInfo->getInstanceModuleOwner(context.isGeneric()).get()
  865. );
  866. // Fix up the canonical name of the module. The previous setOwner()
  867. // sets the canonical as if the module were directly owned by the
  868. // parent module, but that may not be the case if the generic is
  869. // defined in a nested context (e.g. in a class).
  870. module->setNamespaceName(moduleName);
  871. instantiateGeneric(this, context, *modContext, types);
  872. // after we're done parsing, change the owner to the actual owner so
  873. // that names are generated correctly.
  874. // use the source path of the owner
  875. module->sourcePath = owner->sourcePath;
  876. module->sourceDigest = owner->sourceDigest;
  877. module->cacheable = true;
  878. module->close(*modContext);
  879. // store the module in the in-memory cache
  880. context.construct->registerModule(module.get());
  881. nameInModule = name;
  882. } else {
  883. nameInModule = newTypeName;
  884. }
  885. //
  886. // extract the type out of the newly created module and store it in the
  887. // specializations cache
  888. result = extractInstantiation(module.get(), types);
  889. if (result->isStub())
  890. ModuleStubPtr::rcast(module)->registerCallback(
  891. new FixStubbedInstantiation(this, result, types)
  892. );
  893. // record a dependency on the owner's module
  894. context.ns->getModule()->addDependency(module.get());
  895. return result;
  896. }
  897. bool TypeDef::isConstant() {
  898. return true;
  899. }
  900. void TypeDef::getDependents(std::vector<TypeDefPtr> &deps) {}
  901. void TypeDef::dump(ostream &out, const string &prefix) const {
  902. out << prefix << "class " << getFullName() << " {" << endl;
  903. string childPrefix = prefix + " ";
  904. for (TypeVec::const_iterator baseIter = parents.begin();
  905. baseIter != parents.end();
  906. ++baseIter
  907. ) {
  908. out << childPrefix << "parent:" << endl;
  909. (*baseIter)->dump(out, childPrefix+" ");
  910. }
  911. for (VarDefMap::const_iterator iter = beginDefs(); iter != endDefs();
  912. ++iter
  913. )
  914. iter->second->dump(out, childPrefix);
  915. out << prefix << "}" << endl;
  916. }
  917. bool TypeDef::isSerializable() const {
  918. if (meta)
  919. return false;
  920. else
  921. return VarDef::isSerializable();
  922. }
  923. void TypeDef::addDependenciesTo(ModuleDef *mod, VarDef::Set &added) const {
  924. // if we've already dealt with this type, quit.
  925. if (!added.insert(this).second)
  926. return;
  927. mod->addDependency(VarDef::getModule());
  928. // compute dependencies from all non-private symbols
  929. for (VarDefMap::const_iterator iter = defs.begin(); iter != defs.end();
  930. ++iter
  931. ) {
  932. if (iter->first.compare(0, 2, "__"))
  933. iter->second->addDependenciesTo(mod, added);
  934. }
  935. }
  936. void TypeDef::serializeExtern(Serializer &serializer) const {
  937. VarDef::serializeExternRef(serializer, &genericParms);
  938. }
  939. void TypeDef::serializeDef(Serializer &serializer) const {
  940. serializer.write(Serializer::typeId, "kind");
  941. int objectId = serializer.getObjectId(this);
  942. SPUG_CHECK(objectId != -1,
  943. "Type " << getFullName() << " was not registered in the "
  944. "declarations for this module."
  945. );
  946. serializer.write(objectId, "objectId");
  947. // XXX isGeneric is already in the decl.
  948. serializer.write(generic ? 1 : 0, "isGeneric");
  949. if (generic) {
  950. Serializer::StackFrame<Serializer> digestState(serializer, false);
  951. genericInfo->serialize(serializer);
  952. } else {
  953. int flags = (pointer ? 1 : 0) |
  954. (hasVTable ? 2 : 0) |
  955. (abstract ? 4 : 0);
  956. serializer.write(flags, "flags");
  957. serializer.write(parents.size(), "#bases");
  958. for (TypeVec::const_iterator i = parents.begin();
  959. i != parents.end();
  960. ++i
  961. )
  962. (*i)->serialize(serializer, false, 0);
  963. // serialize the optional fields for generic instantiations.
  964. if (templateType) {
  965. ostringstream temp;
  966. Serializer sub(serializer, temp);
  967. sub.write(CRACK_PB_KEY(1, ref), "templateType.header");
  968. templateType->serialize(sub, false, 0);
  969. for (TypeVec::const_iterator iter = genericParms.begin();
  970. iter != genericParms.end();
  971. ++iter
  972. ) {
  973. // field id = 2 (<< 3) | type = 3 (reference)
  974. sub.write(CRACK_PB_KEY(2, ref),
  975. "genericParms[i].header"
  976. );
  977. (*iter)->serialize(sub, false, 0);
  978. }
  979. serializer.write(temp.str(), "optional");
  980. } else {
  981. serializer.write(0, "optional");
  982. }
  983. Namespace::serializeDefs(serializer);
  984. }
  985. }
  986. void TypeDef::serializeAlias(Serializer &serializer,
  987. const string &alias
  988. ) const {
  989. serializer.write(Serializer::typeAliasId, "kind");
  990. serializer.write(alias, "alias");
  991. serializeExternRef(serializer, 0);
  992. }
  993. void TypeDef::serialize(Serializer &serializer, bool writeKind,
  994. const Namespace *ns
  995. ) const {
  996. if (writeKind) {
  997. // We only write "kind" when serializing from a namespace. This
  998. // should never happen for an alias.
  999. SPUG_CHECK(VarDef::getModule() == serializer.module,
  1000. "Attempted to serialize an alias for " << getFullName() <<
  1001. " from a namespace"
  1002. );
  1003. // It should also never happen for a reference, and we don't want to
  1004. // treat type references the same way so we just serialize the
  1005. // definition.
  1006. serializeDef(serializer);
  1007. return;
  1008. }
  1009. if (serializer.writeObject(this, "type")) {
  1010. ModuleDefPtr module = VarDef::getModule();
  1011. if (module != serializer.module) {
  1012. // write an "Extern" (but not a reference, we're already in a
  1013. // reference to the object we'd be externing)
  1014. if (templateType) {
  1015. // If this is a generic instantiation, write the base type
  1016. // with our parameters.
  1017. templateType->serializeExternCommon(serializer,
  1018. &genericParms
  1019. );
  1020. } else {
  1021. serializeExternCommon(serializer, 0);
  1022. }
  1023. } else {
  1024. // For local types, this function should always just produce an
  1025. // object reference because local types are declared before defs.
  1026. // If we got here, something's wrong.
  1027. SPUG_CHECK(false,
  1028. "Serializing full type " << getFullName() <<
  1029. " from a reference."
  1030. );
  1031. }
  1032. }
  1033. }
  1034. int TypeDef::serializeDecl(Serializer &serializer) {
  1035. serializer.write(name, "name");
  1036. serializer.write(generic ? 1 : 0, "isGeneric");
  1037. int result = serializer.registerObject(this);
  1038. serializeTypeDecls(serializer);
  1039. return result;
  1040. }
  1041. namespace {
  1042. struct TypeDefReader : public Deserializer::ObjectReader {
  1043. virtual spug::RCBasePtr read(Deserializer &deser) const {
  1044. return VarDef::deserializeTypeAliasBody(deser);
  1045. }
  1046. };
  1047. } // anon namespace
  1048. TypeDefPtr TypeDef::deserializeRef(Deserializer &deser, const char *name) {
  1049. Deserializer::ReadObjectResult readObj =
  1050. deser.readObject(TypeDefReader(), name ? name : "type");
  1051. return TypeDefPtr::arcast(readObj.object);
  1052. }
  1053. TypeDefPtr TypeDef::deserializeTypeDef(Deserializer &deser, const char *name) {
  1054. // Read the object id and retrieve the existing object.
  1055. int objectId = deser.readUInt("id");
  1056. TypeDefPtr type = deser.getObject(objectId);
  1057. SPUG_CHECK(type, "Type object " << objectId << " not registered.");
  1058. if (Serializer::trace)
  1059. cerr << "deserializing body of type " << type->getFullName() << endl;
  1060. // is this a generic?
  1061. unsigned isGeneric = deser.readUInt("isGeneric");
  1062. if (isGeneric) {
  1063. Serializer::StackFrame<Deserializer> digestState(deser, false);
  1064. type->genericInfo = Generic::deserialize(deser);
  1065. type->genericInfo->ns = deser.context->ns.get();
  1066. type->genericInfo->seedCompileNS(*deser.context);
  1067. type->generic = new TypeDef::SpecializationCache();
  1068. } else {
  1069. // flags
  1070. int flags = deser.readUInt("flags");
  1071. type->pointer = (flags & 1) ? true : false;
  1072. type->hasVTable = (flags & 2) ? true : false;
  1073. type->abstract = (flags & 4) ? true : false;
  1074. // bases
  1075. int count = deser.readUInt("#bases");
  1076. TypeDef::TypeVec bases(count);
  1077. for (int i = 0; i < count; ++i)
  1078. bases[i] = TypeDef::deserializeRef(deser, "bases[i]");
  1079. type->parents = bases;
  1080. // check for optional fields
  1081. CRACK_PB_BEGIN(deser, 256, optional);
  1082. CRACK_PB_FIELD(1, ref)
  1083. type->templateType =
  1084. deserializeRef(optionalDeser, "templateType").get();
  1085. break;
  1086. CRACK_PB_FIELD(2, ref)
  1087. type->genericParms.push_back(
  1088. deserializeRef(optionalDeser, "genericParms")
  1089. );
  1090. break;
  1091. CRACK_PB_END
  1092. // 'defs' - fill in the body.
  1093. ContextPtr classContext =
  1094. deser.context->createSubContext(Context::instance,
  1095. type.get(),
  1096. &type->name
  1097. );
  1098. ContextStackFrame<Deserializer> cstack(deser, classContext.get());
  1099. type->deserializeDefs(deser);
  1100. }
  1101. if (Serializer::trace)
  1102. cerr << "done deserializing type " << type->getFullName() << endl;
  1103. type->complete = true;
  1104. return type;
  1105. }
  1106. int TypeDef::deserializeDecl(Deserializer &deser, int nextId) {
  1107. string name = deser.readString(Serializer::varNameSize, "name");
  1108. int isGeneric = deser.readUInt("isGeneric");
  1109. TypeDefPtr type;
  1110. if (isGeneric)
  1111. type =
  1112. new TypeDef(deser.context->construct->classType.get(), name, true);
  1113. else
  1114. type = deser.context->builder.materializeType(*deser.context, name);
  1115. deser.registerObject(nextId, type.get());
  1116. deser.context->ns->addDef(type.get());
  1117. // do the nested declarations against the new context.
  1118. ContextPtr classContext =
  1119. deser.context->createSubContext(Context::instance, type.get(),
  1120. &type->name
  1121. );
  1122. ContextStackFrame<Deserializer> frame(deser, classContext.get());
  1123. return deserializeTypeDecls(deser, nextId + 1);
  1124. }
  1125. VarDefPtr TypeDef::replaceAllStubs(Context &context) {
  1126. if (stubFree)
  1127. return this;
  1128. stubFree = true;
  1129. VarDefPtr replacement = replaceStub(context);
  1130. if (replacement)
  1131. return replacement;
  1132. // fix all bases
  1133. for (TypeVec::iterator iter = parents.begin(); iter != parents.end();
  1134. ++iter
  1135. )
  1136. *iter = (*iter)->replaceAllStubs(context);
  1137. // if this is a generic specialization, fix all parameters
  1138. if (genericParms.size()) {
  1139. for (TypeVec::iterator iter = genericParms.begin();
  1140. iter != genericParms.end();
  1141. ++iter
  1142. )
  1143. *iter = (*iter)->replaceAllStubs(context);
  1144. }
  1145. // if this is a generic instantiation, fix all specializations.
  1146. if (generic) {
  1147. for (SpecializationCache::iterator iter = generic->begin();
  1148. iter != generic->end();
  1149. ++iter
  1150. )
  1151. iter->second = iter->second->replaceAllStubs(context);
  1152. }
  1153. if (templateType)
  1154. templateType =
  1155. TypeDefPtr::rcast(templateType->replaceAllStubs(context));
  1156. // We don't need to worry about meta, metas only have dependencies on
  1157. // other metas, and the meta itself should never be stubbed since it is
  1158. // created at the same time as the class.
  1159. for (VarDefMap::iterator iter = defs.begin(); iter != defs.

Large files files are truncated, but you can click here to view the full file