source: branches/0.17.x/abcl/src/org/armedbear/lisp/Layout.java

Last change on this file was 12254, checked in by ehuelsmann, 16 years ago

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.0 KB
Line 
1/*
2 * Layout.java
3 *
4 * Copyright (C) 2003-2006 Peter Graves
5 * $Id: Layout.java 12254 2009-11-06 20:07:54Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public final class Layout extends LispObject
37{
38  public final LispClass lispClass;
39  public final EqHashTable slotTable;
40
41  private final LispObject[] slotNames;
42  private final LispObject sharedSlots;
43
44  private boolean invalid;
45
46  public Layout(LispClass lispClass, LispObject instanceSlots, LispObject sharedSlots)
47  {
48    this.lispClass = lispClass;
49    Debug.assertTrue(instanceSlots.listp());
50    int length = 0;
51    try
52      {
53        length = instanceSlots.length();
54      }
55    catch (Throwable t)
56      {
57        // Shouldn't happen.
58        Debug.trace(t);
59      }
60    slotNames = new LispObject[length];
61    int i = 0;
62    try
63      {
64        while (instanceSlots != NIL)
65          {
66            slotNames[i++] = instanceSlots.car();
67            instanceSlots = instanceSlots.cdr();
68          }
69      }
70    catch (Throwable t)
71      {
72        // Shouldn't happen.
73        Debug.trace(t);
74      }
75    Debug.assertTrue(i == length);
76    this.sharedSlots = sharedSlots;
77    slotTable = initializeSlotTable(slotNames);
78  }
79
80  public Layout(LispClass lispClass, LispObject[] instanceSlotNames,
81                LispObject sharedSlots)
82  {
83    this.lispClass = lispClass;
84    this.slotNames = instanceSlotNames;
85    this.sharedSlots = sharedSlots;
86    slotTable = initializeSlotTable(slotNames);
87  }
88
89  // Copy constructor.
90  private Layout(Layout oldLayout)
91  {
92    lispClass = oldLayout.lispClass;
93    slotNames = oldLayout.slotNames;
94    sharedSlots = oldLayout.sharedSlots;
95    slotTable = initializeSlotTable(slotNames);
96  }
97
98  private EqHashTable initializeSlotTable(LispObject[] slotNames)
99  {
100    EqHashTable ht = new EqHashTable(slotNames.length, NIL, NIL);
101    for (int i = slotNames.length; i-- > 0;)
102      ht.put(slotNames[i], Fixnum.getInstance(i));
103    return ht;
104  }
105
106  @Override
107  public LispObject getParts()
108  {
109    LispObject result = NIL;
110    result = result.push(new Cons("class", lispClass));
111    for (int i = 0; i < slotNames.length; i++)
112      {
113        result = result.push(new Cons("slot " + i, slotNames[i]));
114      }
115    result = result.push(new Cons("shared slots", sharedSlots));
116    return result.nreverse();
117  }
118
119  public boolean isInvalid()
120  {
121    return invalid;
122  }
123
124  public void invalidate()
125  {
126    invalid = true;
127  }
128
129  public LispObject[] getSlotNames()
130  {
131    return slotNames;
132  }
133
134  public int getLength()
135  {
136    return slotNames.length;
137  }
138
139  public LispObject getSharedSlots()
140  {
141    return sharedSlots;
142  }
143
144  @Override
145  public String writeToString()
146  {
147    return unreadableString(Symbol.LAYOUT);
148  }
149
150  // Generates a list of slot definitions for the slot names in this layout.
151  protected LispObject generateSlotDefinitions()
152  {
153    LispObject list = NIL;
154    try
155      {
156        for (int i = slotNames.length; i-- > 0;)
157          list = list.push(new SlotDefinition(slotNames[i], NIL));
158      }
159    catch (Throwable t)
160      {
161        // Shouldn't happen.
162        Debug.trace(t);
163      }
164    return list;
165  }
166
167  // ### make-layout
168  private static final Primitive MAKE_LAYOUT =
169    new Primitive("make-layout", PACKAGE_SYS, true,
170                  "class instance-slots class-slots")
171    {
172      @Override
173      public LispObject execute(LispObject first, LispObject second,
174                                LispObject third)
175
176      {
177          return new Layout(checkClass(first), checkList(second),
178                              checkList(third));
179      }
180
181    };
182
183  // ### layout-class
184  private static final Primitive LAYOUT_CLASS =
185    new Primitive("layout-class", PACKAGE_SYS, true, "layout")
186    {
187      @Override
188      public LispObject execute(LispObject arg)
189      {
190          return checkLayout(arg).lispClass;
191      }
192    };
193
194  // ### layout-length
195  private static final Primitive LAYOUT_LENGTH =
196    new Primitive("layout-length", PACKAGE_SYS, true, "layout")
197    {
198      @Override
199      public LispObject execute(LispObject arg)
200      {
201          return Fixnum.getInstance(checkLayout(arg).slotNames.length);
202      }
203    };
204
205  public int getSlotIndex(LispObject slotName)
206  {
207    LispObject index = slotTable.get(slotName);
208    if (index != null)
209      return ((Fixnum)index).value;
210    return -1;
211  }
212
213  public LispObject getSharedSlotLocation(LispObject slotName)
214
215  {
216    LispObject rest = sharedSlots;
217    while (rest != NIL)
218      {
219        LispObject location = rest.car();
220        if (location.car() == slotName)
221          return location;
222        rest = rest.cdr();
223      }
224    return null;
225  }
226
227  // ### layout-slot-index layout slot-name => index
228  private static final Primitive LAYOUT_SLOT_INDEX =
229    new Primitive("layout-slot-index", PACKAGE_SYS, true)
230    {
231      @Override
232      public LispObject execute(LispObject first, LispObject second)
233
234      {
235          final LispObject slotNames[] = checkLayout(first).slotNames;
236          for (int i = slotNames.length; i-- > 0;)
237            {
238              if (slotNames[i] == second)
239                return Fixnum.getInstance(i);
240            }
241          return NIL;
242      }
243    };
244
245  // ### layout-slot-location layout slot-name => location
246  private static final Primitive LAYOUT_SLOT_LOCATION =
247    new Primitive("layout-slot-location", PACKAGE_SYS, true, "layout slot-name")
248    {
249      @Override
250      public LispObject execute(LispObject first, LispObject second)
251
252      {
253                final Layout layOutFirst = checkLayout(first);
254            final LispObject slotNames[] = layOutFirst.slotNames;
255            final int limit = slotNames.length;
256            for (int i = 0; i < limit; i++)
257              {
258                if (slotNames[i] == second)
259                  return Fixnum.getInstance(i);
260              }
261            // Reaching here, it's not an instance slot.
262            LispObject rest = layOutFirst.sharedSlots;
263            while (rest != NIL)
264              {
265                LispObject location = rest.car();
266                if (location.car() == second)
267                  return location;
268                rest = rest.cdr();
269              }
270            return NIL;
271          }
272    };
273
274  // ### %make-instances-obsolete class => class
275  private static final Primitive _MAKE_INSTANCES_OBSOLETE =
276    new Primitive("%make-instances-obsolete", PACKAGE_SYS, true, "class")
277    {
278      @Override
279      public LispObject execute(LispObject arg)
280      {
281        final LispClass lispClass = checkClass(arg);
282        Layout oldLayout = lispClass.getClassLayout();
283        Layout newLayout = new Layout(oldLayout);
284        lispClass.setClassLayout(newLayout);
285        oldLayout.invalidate();
286        return arg;
287      }
288    };
289}
Note: See TracBrowser for help on using the repository browser.