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

Last change on this file was 12513, checked in by ehuelsmann, 15 years ago

Remove 'private' keyword to eliminate the Java requirement

for the compiler to generate synthetic accessors: functions that
don't appear in the source but do appear in the class file.

Patch by: Douglas Miles <dmiles _at_ users.sf.net>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1/*
2 * Layout.java
3 *
4 * Copyright (C) 2003-2006 Peter Graves
5 * $Id: Layout.java 12513 2010-03-02 22:35:36Z 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
36import static org.armedbear.lisp.Lisp.*;
37
38public class Layout extends LispObject
39{
40  private final LispClass lispClass;
41  public final EqHashTable slotTable;
42
43  final LispObject[] slotNames;
44  final LispObject sharedSlots;
45
46  private boolean invalid;
47
48  public Layout(LispClass lispClass, LispObject instanceSlots, LispObject sharedSlots)
49  {
50    this.lispClass = lispClass;
51    Debug.assertTrue(instanceSlots.listp());
52    int length = instanceSlots.length();
53    slotNames = new LispObject[length];
54    int i = 0;
55
56    while (instanceSlots != NIL)
57      {
58        slotNames[i++] = instanceSlots.car();
59        instanceSlots = instanceSlots.cdr();
60      }
61
62    Debug.assertTrue(i == length);
63    this.sharedSlots = sharedSlots;
64    slotTable = initializeSlotTable(slotNames);
65  }
66
67  public Layout(LispClass lispClass, LispObject[] instanceSlotNames,
68                LispObject sharedSlots)
69  {
70    this.lispClass = lispClass;
71    this.slotNames = instanceSlotNames;
72    this.sharedSlots = sharedSlots;
73    slotTable = initializeSlotTable(slotNames);
74  }
75
76  // Copy constructor.
77  Layout(Layout oldLayout)
78  {
79    lispClass = oldLayout.getLispClass();
80    slotNames = oldLayout.slotNames;
81    sharedSlots = oldLayout.sharedSlots;
82    slotTable = initializeSlotTable(slotNames);
83  }
84
85  private EqHashTable initializeSlotTable(LispObject[] slotNames)
86  {
87    EqHashTable ht = new EqHashTable(slotNames.length, NIL, NIL);
88    for (int i = slotNames.length; i-- > 0;)
89      ht.put(slotNames[i], Fixnum.getInstance(i));
90    return ht;
91  }
92
93  @Override
94  public LispObject getParts()
95  {
96    LispObject result = NIL;
97    result = result.push(new Cons("class", getLispClass()));
98    for (int i = 0; i < slotNames.length; i++)
99      {
100        result = result.push(new Cons("slot " + i, slotNames[i]));
101      }
102    result = result.push(new Cons("shared slots", sharedSlots));
103    return result.nreverse();
104  }
105
106  public LispClass getLispClass()
107  {
108    return lispClass;
109  }
110
111  public boolean isInvalid()
112  {
113    return invalid;
114  }
115
116  public void invalidate()
117  {
118    invalid = true;
119  }
120
121  public LispObject[] getSlotNames()
122  {
123    return slotNames;
124  }
125
126  public int getLength()
127  {
128    return slotNames.length;
129  }
130
131  public LispObject getSharedSlots()
132  {
133    return sharedSlots;
134  }
135
136  @Override
137  public String writeToString()
138  {
139    return unreadableString(Symbol.LAYOUT);
140  }
141
142  // Generates a list of slot definitions for the slot names in this layout.
143  protected LispObject generateSlotDefinitions()
144  {
145    LispObject list = NIL;
146    for (int i = slotNames.length; i-- > 0;)
147      list = list.push(new SlotDefinition(slotNames[i], NIL));
148
149    return list;
150  }
151
152  // ### make-layout
153  private static final Primitive MAKE_LAYOUT =
154    new Primitive("make-layout", PACKAGE_SYS, true,
155                  "class instance-slots class-slots")
156    {
157      @Override
158      public LispObject execute(LispObject first, LispObject second,
159                                LispObject third)
160
161      {
162          return new Layout(checkClass(first), checkList(second),
163                              checkList(third));
164      }
165
166    };
167
168  // ### layout-class
169  private static final Primitive LAYOUT_CLASS =
170    new Primitive("layout-class", PACKAGE_SYS, true, "layout")
171    {
172      @Override
173      public LispObject execute(LispObject arg)
174      {
175          return checkLayout(arg).getLispClass();
176      }
177    };
178
179  // ### layout-length
180  private static final Primitive LAYOUT_LENGTH =
181    new Primitive("layout-length", PACKAGE_SYS, true, "layout")
182    {
183      @Override
184      public LispObject execute(LispObject arg)
185      {
186          return Fixnum.getInstance(checkLayout(arg).slotNames.length);
187      }
188    };
189
190  public int getSlotIndex(LispObject slotName)
191  {
192    LispObject index = slotTable.get(slotName);
193    if (index != null)
194      return ((Fixnum)index).value;
195    return -1;
196  }
197
198  public LispObject getSharedSlotLocation(LispObject slotName)
199
200  {
201    LispObject rest = sharedSlots;
202    while (rest != NIL)
203      {
204        LispObject location = rest.car();
205        if (location.car() == slotName)
206          return location;
207        rest = rest.cdr();
208      }
209    return null;
210  }
211
212  // ### layout-slot-index layout slot-name => index
213  private static final Primitive LAYOUT_SLOT_INDEX =
214    new Primitive("layout-slot-index", PACKAGE_SYS, true)
215    {
216      @Override
217      public LispObject execute(LispObject first, LispObject second)
218
219      {
220          final LispObject slotNames[] = checkLayout(first).slotNames;
221          for (int i = slotNames.length; i-- > 0;)
222            {
223              if (slotNames[i] == second)
224                return Fixnum.getInstance(i);
225            }
226          return NIL;
227      }
228    };
229
230  // ### layout-slot-location layout slot-name => location
231  private static final Primitive LAYOUT_SLOT_LOCATION =
232    new Primitive("layout-slot-location", PACKAGE_SYS, true, "layout slot-name")
233    {
234      @Override
235      public LispObject execute(LispObject first, LispObject second)
236
237      {
238                final Layout layOutFirst = checkLayout(first);
239            final LispObject slotNames[] = layOutFirst.slotNames;
240            final int limit = slotNames.length;
241            for (int i = 0; i < limit; i++)
242              {
243                if (slotNames[i] == second)
244                  return Fixnum.getInstance(i);
245              }
246            // Reaching here, it's not an instance slot.
247            LispObject rest = layOutFirst.sharedSlots;
248            while (rest != NIL)
249              {
250                LispObject location = rest.car();
251                if (location.car() == second)
252                  return location;
253                rest = rest.cdr();
254              }
255            return NIL;
256          }
257    };
258
259  // ### %make-instances-obsolete class => class
260  private static final Primitive _MAKE_INSTANCES_OBSOLETE =
261    new Primitive("%make-instances-obsolete", PACKAGE_SYS, true, "class")
262    {
263      @Override
264      public LispObject execute(LispObject arg)
265      {
266        final LispClass lispClass = checkClass(arg);
267        Layout oldLayout = lispClass.getClassLayout();
268        Layout newLayout = new Layout(oldLayout);
269        lispClass.setClassLayout(newLayout);
270        oldLayout.invalidate();
271        return arg;
272      }
273    };
274}
Note: See TracBrowser for help on using the repository browser.