src/compiler/Scopes.cpp
author David Anderson <dvander@alliedmods.net>
Mon Nov 19 01:13:44 2012 -0800 (2012-11-19)
changeset 220 5df4a112967d
parent 195 c1ba166f3fc4
child 256 3c184218462d
permissions -rw-r--r--
Re-added parameter support.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Zone.h"
    20 #include "../Types.h"
    21 #include "../TypeManager.h"
    22 #include "../Strings.h"
    23 #include "../Environments.h"
    24 #include "../Structures.h"
    25 #include "CompileContext.h"
    26 #include "Scopes.h"
    27 #include "../Spaces-inl.h"
    28 #include "../Heap-inl.h"
    29 
    30 using namespace ke;
    31 
    32 Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
    33   : pool_(pool),
    34     kind_(kind),
    35     enclosing_(enclosing)
    36 {
    37 }
    38 
    39 bool
    40 Scope::initialize()
    41 {
    42     if (enclosing_ && !enclosing_->children_.append(this))
    43         return false;
    44     return true;
    45 }
    46 
    47 void
    48 Scope::unlink()
    49 {
    50     assert(empty());
    51 
    52     assert(enclosing_->children_[enclosing_->children_.length() - 1] == this);
    53     enclosing_->children_.pop();
    54 
    55     // OOM here is swallowed and checked after compilation.
    56     // :TODO: make the above true.
    57     for (size_t i = 0; i < children_.length(); i++)
    58         enclosing_->children_.append(children_[i]);
    59 }
    60 
    61 Scope *
    62 Scope::unlinkIfEmpty()
    63 {
    64     if (empty()) {
    65         unlink();
    66         return NULL;
    67     }
    68     return this;
    69 }
    70 
    71 Symbol *
    72 Scope::localLookup(Handle<String> name)
    73 {
    74     for (size_t i = 0; i < names_.length(); i++) {
    75         if (names_[i]->name() == name)
    76             return names_[i];
    77     }
    78     return NULL;
    79 }
    80 
    81 Symbol  *
    82 Scope::lookup(Handle<String> name)
    83 {
    84     for (Scope *scope = this; scope; scope = scope->enclosing()) {
    85         if (Symbol *bound = scope->localLookup(name))
    86             return bound;
    87     }
    88     return NULL;
    89 }
    90 
    91 #if 0
    92 void
    93 Scope::setUsesLifoHeap()
    94 {
    95     // Only one lifo slot is needed per scope.
    96 #if 0
    97     if (lifoSlot_)
    98         return;
    99 #endif
   100 
   101     // If the parent of this scope is the function scope, then this is the
   102     // function's block scope, and the lifo slot is part of the Frame instead.
   103     // Note we can get a function scope here if we're making a temporary in a
   104     // function with no local variables.
   105     if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
   106         return;
   107 
   108     Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
   109     if (!type)
   110         return;
   111 
   112     Local<String> name(ZONE());
   113 #if 0
   114     lifoSlot_ = new (pool_) Variable(this, name, SourcePosition());
   115     lifoSlot_->setType(type);
   116 #endif
   117 }
   118 #endif
   119 
   120 bool
   121 Scope::addSymbol(Symbol *sym)
   122 {
   123     return names_.append(sym);
   124 }
   125 
   126 LocalScope::LocalScope(PoolAllocator &pool)
   127   : Scope(pool, Scope::BLOCK, NULL)
   128 {
   129 }
   130 
   131 LocalScope *
   132 LocalScope::New(PoolAllocator &pool)
   133 {
   134     LocalScope *scope = new (pool) LocalScope(pool);
   135     if (!scope->initialize())
   136         return NULL;
   137 
   138     return scope;
   139 }
   140 
   141 ArgumentScope::ArgumentScope(PoolAllocator &pool)
   142   : Scope(pool, Scope::FUNCTION, NULL)
   143 {
   144 }
   145 
   146 ArgumentScope *
   147 ArgumentScope::New(PoolAllocator &pool)
   148 {
   149     ArgumentScope *scope = new (pool) ArgumentScope(pool);
   150     if (!scope->initialize())
   151         return NULL;
   152 
   153     return scope;
   154 }
   155 
   156 GlobalScope::GlobalScope(PoolAllocator &pool, ImportScope *parent)
   157   : Scope(pool, Scope::GLOBAL, parent)
   158 {
   159 }
   160 
   161 GlobalScope *
   162 GlobalScope::New(PoolAllocator &pool, ImportScope *parent)
   163 {
   164     GlobalScope *scope = new (pool) GlobalScope(pool, parent);
   165     if (!scope->initialize())
   166         return NULL;
   167 
   168     return scope;
   169 }
   170 
   171 bool
   172 GlobalScope::addPublic(Symbol *sym)
   173 {
   174     return publics_.append(sym);
   175 }
   176 
   177 Symbol *
   178 GlobalScope::findPublic(Handle<String> name)
   179 {
   180     for (size_t i = 0; i < publics_.length(); i++) {
   181         if (publics_[i]->name() == name)
   182             return publics_[i];
   183     }
   184     return NULL;
   185 }
   186 
   187 Struct *
   188 GlobalScope::build(Zone *zone)
   189 {
   190     Local<FixedArray> descriptors(zone, FixedArray::New(zone, names_.length(), Heap::Tenure_Old));
   191 
   192     for (size_t i = 0; i < names_.length(); i++) {
   193         Handle<String> name = names_[i]->name();
   194         Handle<Type> type = names_[i]->type();
   195         assert(type);
   196 
   197         Local<Descriptor> desc(zone, Descriptor::New(zone, name, type));
   198         if (!desc)
   199             return NULL;
   200         
   201         descriptors->set(zone, i, desc);
   202     }
   203 
   204     Local<StructType> type(zone, StructType::New(zone, Handle<String>::Null(), descriptors));
   205     if (!type)
   206         return NULL;
   207 
   208     Local<StructMap> map(zone, type->newMap());
   209     return Struct::New(zone, map, Heap::Tenure_Old);
   210 }
   211 
   212 ImportScope::ImportScope(PoolAllocator &pool)
   213   : Scope(pool, Scope::IMPORT, NULL)
   214 {
   215 }
   216 
   217 ImportScope *
   218 ImportScope::New(PoolAllocator &pool)
   219 {
   220     ImportScope *scope = new (pool) ImportScope(pool);
   221     if (!scope->initialize())
   222         return NULL;
   223 
   224     return scope;
   225 }