1.1 --- a/src/compiler/NameBinding.cpp Sat Jan 12 16:35:26 2013 -0800
1.2 +++ b/src/compiler/NameBinding.cpp Sun Jan 27 17:34:30 2013 -0800
1.3 @@ -137,12 +137,14 @@
1.4 return;
1.5 }
1.6
1.7 - bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> type) {
1.8 + bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> effective) {
1.9 Local<String> tag(zone_, zone_->makeSymbol(name));
1.10 if (!tag)
1.11 return false;
1.12
1.13 - TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type);
1.14 + Local<Type> type(zone_, zone_->types()->getType());
1.15 +
1.16 + TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type, effective);
1.17 return scope->addSymbol(sym);
1.18 }
1.19
1.20 @@ -214,7 +216,8 @@
1.21 return;
1.22
1.23 if (name) {
1.24 - TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
1.25 + Local<Type> symType(zone_, zone_->types()->getType());
1.26 + TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, symType, type);
1.27 if (!registerName(scope, sym))
1.28 return;
1.29
1.30 @@ -224,6 +227,10 @@
1.31 }
1.32 }
1.33
1.34 + // We want each field of the expression to qualify as a constant expression.
1.35 + if ((type = zone_->types()->qualify(type, TypeQual_ConstExpr)) == NULL)
1.36 + return;
1.37 +
1.38 int value = 0;
1.39 for (size_t i = 0; i < node->entries()->length(); i++) {
1.40 EnumStatement::Entry &entry = node->entries()->at(i);
1.41 @@ -237,7 +244,7 @@
1.42 assert(box.type() == PrimitiveType_Int32);
1.43 value = box.toInt();
1.44 }
1.45 -
1.46 +
1.47 ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
1.48 if (!registerName(scope, sym))
1.49 return;
1.50 @@ -246,6 +253,7 @@
1.51 return;
1.52 }
1.53
1.54 + entry.sym = sym;
1.55 value++;
1.56 }
1.57 }
1.58 @@ -756,7 +764,7 @@
1.59 return NULL;
1.60 }
1.61
1.62 - type = sym->type();
1.63 + type = sym->toType()->effective();
1.64 }
1.65
1.66 return zone_->types()->qualify(type, quals);
1.67 @@ -771,6 +779,18 @@
1.68
1.69 class GlobalBuilder : public NameBinderBase
1.70 {
1.71 + typedef ScopedRoot<Descriptor> ScopedDescriptor;
1.72 + struct PrimitiveFill {
1.73 + ScopedDescriptor *desc;
1.74 + BoxedPrimitive prim;
1.75 +
1.76 + PrimitiveFill(ScopedDescriptor *desc, BoxedPrimitive prim)
1.77 + : desc(desc),
1.78 + prim(prim)
1.79 + {
1.80 + }
1.81 + };
1.82 +
1.83 public:
1.84 GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.85 : NameBinderBase(zone, cc, unit),
1.86 @@ -788,6 +808,17 @@
1.87 stmt->accept(this);
1.88 }
1.89
1.90 + Local<Struct> globals(zone_, createGlobals());
1.91 + if (!globals)
1.92 + return NULL;
1.93 +
1.94 + populate(globals);
1.95 +
1.96 + return globals;
1.97 + }
1.98 +
1.99 + private:
1.100 + Struct *createGlobals() {
1.101 Local<FixedArray> descs(zone_, FixedArray::New(zone_, descriptors_.length(), Heap::Tenure_Old));
1.102 if (!descs)
1.103 return NULL;
1.104 @@ -804,7 +835,47 @@
1.105 return Struct::New(zone_, map, Heap::Tenure_Old);
1.106 }
1.107
1.108 + void populate(Handle<Struct> globals) {
1.109 + // This is a huge hack, but it's probably better than a full extra
1.110 + // pass. The problem is that until we have all the descriptors, we
1.111 + // can't start setting constexprs in the struct, and we need to set
1.112 + // them now so they're available during full semantic analysis. To
1.113 + // work around this, we build up the list of values we need to set
1.114 + // as we build up descriptors, and then populate the global struct
1.115 + // with this set.
1.116 + //
1.117 + // Note, this code is also kind of dead until we support linking. We
1.118 + // handle constexprs explicitly in importFrom(), by sniffing out the
1.119 + // symbol type. That code will go away later.
1.120 + for (size_t i = 0; i < primitiveFills_.length(); i++) {
1.121 + const PrimitiveFill &fill = primitiveFills_[i];
1.122 + assert(fill.prim.type() == PrimitiveType_Int32);
1.123 + globals->set(*fill.desc, fill.prim.toInt());
1.124 + }
1.125 + }
1.126 +
1.127 + public:
1.128 void visitEnumStatement(EnumStatement *stmt) {
1.129 + if (stmt->visibility() != TOK_PUBLIC || !stmt->name())
1.130 + return;
1.131 +
1.132 + Local<Type> type(zone_, zone_->types()->getType());
1.133 + Descriptor *desc = Descriptor::New(zone_, stmt->name(), type, Descriptor::Public);
1.134 + if (!desc)
1.135 + return;
1.136 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.137 + return;
1.138 +
1.139 + for (size_t i = 0; i < stmt->entries()->length(); i++) {
1.140 + EnumStatement::Entry &e = stmt->entries()->at(i);
1.141 + ScopedDescriptor *desc = new (pool_) ScopedDescriptor(Descriptor::New(zone_, e.name, e.sym->type(), Descriptor::Public));
1.142 + if (!desc || !descriptors_.append(desc))
1.143 + return;
1.144 +
1.145 + // Save the value so we can export it immediately.
1.146 + if (!primitiveFills_.append(PrimitiveFill(desc, e.sym->value())))
1.147 + return;
1.148 + }
1.149 }
1.150
1.151 void visitNameProxy(NameProxy *proxy) {
1.152 @@ -917,11 +988,33 @@
1.153 return false;
1.154 }
1.155
1.156 - ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(),
1.157 - import->name(),
1.158 - node->pos(),
1.159 - import->type(),
1.160 - node->importIndex());
1.161 + Symbol *sym;
1.162 + if (import->isType()) {
1.163 + // Fuck it, make a TypeSymbol instead of an ImplicitSymbol. This
1.164 + // makes bindType() much simpler. We may run into problems
1.165 + // implementing linking, but it seems unlikely, as long as we are
1.166 + // exporting Types in module structs.
1.167 + Local<Type> type(zone_, zone_->types()->getType());
1.168 + sym = new (pool_) TypeSymbol(unit_->importScope(),
1.169 + import->name(),
1.170 + type,
1.171 + import->toType()->effective());
1.172 + } else if (import->isConstant()) {
1.173 + // Same deal. No reason to lookup in the module globals if we
1.174 + // already have a symbol.
1.175 + sym = new (pool_) ConstantSymbol(unit_->importScope(),
1.176 + import->name(),
1.177 + node->pos(),
1.178 + import->type(),
1.179 + import->toConstant()->value());
1.180 + } else {
1.181 + sym = new (pool_) ImplicitSymbol(unit_->importScope(),
1.182 + import->name(),
1.183 + node->pos(),
1.184 + import->type(),
1.185 + node->importIndex());
1.186 + }
1.187 +
1.188 if (!unit_->importScope()->addSymbol(sym))
1.189 return false;
1.190
1.191 @@ -963,6 +1056,7 @@
1.192 StructureBufferBuilder builder_;
1.193 Vector<ScopedRoot<Descriptor> *> descriptors_;
1.194 GlobalScope *globalScope_;
1.195 + Vector<PrimitiveFill> primitiveFills_;
1.196 };
1.197
1.198 class NameBinder : public NameBinderBase