1 /* src/vm/linker.c - class linker functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: linker.c 3267 2005-09-21 20:21:48Z twisti $
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "vm/builtin.h"
46 #include "vm/classcache.h"
47 #include "vm/exceptions.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/resolve.h"
51 #include "vm/statistics.h"
52 #include "vm/stringlocal.h"
53 #include "vm/jit/codegen.inc.h"
56 /* global variables ***********************************************************/
58 static s4 interfaceindex; /* sequential numbering of interfaces */
62 /* primitivetype_table *********************************************************
64 Structure for primitive classes: contains the class for wrapping
65 the primitive type, the primitive class, the name of the class for
66 wrapping, the one character type signature and the name of the
69 CAUTION: Don't change the order of the types. This table is indexed
70 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
72 *******************************************************************************/
74 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
75 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
76 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
77 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
78 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
79 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
80 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
81 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
82 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
83 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
84 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
85 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
89 /* private functions **********************************************************/
91 static bool link_primitivetype_table(void);
92 static classinfo *link_class_intern(classinfo *c);
93 static arraydescriptor *link_array(classinfo *c);
94 static void linker_compute_class_values(classinfo *c);
95 static void linker_compute_subclasses(classinfo *c);
96 static void linker_addinterface(classinfo *c, classinfo *ic);
97 static s4 class_highestinterface(classinfo *c);
100 /* linker_init *****************************************************************
102 Initializes the linker subsystem.
104 *******************************************************************************/
106 bool linker_init(void)
108 /* reset interface index */
112 /* link important system classes */
114 if (!link_class(class_java_lang_Object))
117 if (!link_class(class_java_lang_String))
120 if (!link_class(class_java_lang_Cloneable))
123 if (!link_class(class_java_io_Serializable))
127 /* link classes for wrapping primitive types */
129 if (!link_class(class_java_lang_Void))
132 if (!link_class(class_java_lang_Boolean))
135 if (!link_class(class_java_lang_Byte))
138 if (!link_class(class_java_lang_Character))
141 if (!link_class(class_java_lang_Short))
144 if (!link_class(class_java_lang_Integer))
147 if (!link_class(class_java_lang_Long))
150 if (!link_class(class_java_lang_Float))
153 if (!link_class(class_java_lang_Double))
157 /* load some other important classes */
159 if (!link_class(class_java_lang_Class))
162 if (!link_class(class_java_lang_ClassLoader))
165 if (!link_class(class_java_lang_SecurityManager))
168 if (!link_class(class_java_lang_System))
171 if (!link_class(class_java_lang_ThreadGroup))
175 /* some classes which may be used more often */
177 if (!link_class(class_java_lang_StackTraceElement))
180 if (!link_class(class_java_lang_reflect_Constructor))
183 if (!link_class(class_java_lang_reflect_Field))
186 if (!link_class(class_java_lang_reflect_Method))
189 if (!link_class(class_java_security_PrivilegedAction))
192 if (!link_class(class_java_util_Vector))
195 if (!link_class(arrayclass_java_lang_Object))
199 /* create pseudo classes used by the typechecker */
201 /* pseudo class for Arraystubs (extends java.lang.Object) */
203 pseudo_class_Arraystub =
204 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
205 pseudo_class_Arraystub->loaded = true;
206 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
207 pseudo_class_Arraystub->interfacescount = 2;
208 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
209 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
210 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
212 if (!classcache_store_unique(pseudo_class_Arraystub)) {
213 log_text("could not cache pseudo_class_Arraystub");
217 if (!link_class(pseudo_class_Arraystub))
220 /* pseudo class representing the null type */
222 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
223 pseudo_class_Null->loaded = true;
224 pseudo_class_Null->super.cls = class_java_lang_Object;
226 if (!classcache_store_unique(pseudo_class_Null)) {
227 log_text("could not cache pseudo_class_Null");
231 if (!link_class(pseudo_class_Null))
234 /* pseudo class representing new uninitialized objects */
236 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
237 pseudo_class_New->loaded = true;
238 pseudo_class_New->linked = true; /* XXX is this allright? */
239 pseudo_class_New->super.cls = class_java_lang_Object;
241 if (!classcache_store_unique(pseudo_class_New)) {
242 log_text("could not cache pseudo_class_New");
246 /* create classes representing primitive types */
248 if (!link_primitivetype_table())
252 /* Correct vftbl-entries (retarded loading and linking of class */
253 /* java/lang/String). */
255 stringtable_update();
261 /* link_primitivetype_table ****************************************************
263 Create classes representing primitive types.
265 *******************************************************************************/
267 static bool link_primitivetype_table(void)
273 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
276 if (!primitivetype_table[i].name)
279 /* create primitive class */
281 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
283 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
284 c->classUsed = NOTUSED; /* not used initially CO-RT */
287 /* prevent loader from loading primitive class */
291 /* INFO: don't put primitive classes into the classcache */
296 primitivetype_table[i].class_primitive = c;
298 /* create class for wrapping the primitive type */
300 u = utf_new_char(primitivetype_table[i].wrapname);
302 if (!(c = load_class_bootstrap(u)))
305 primitivetype_table[i].class_wrap = c;
306 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
307 primitivetype_table[i].class_wrap->impldBy = NULL;
309 /* create the primitive array class */
311 if (primitivetype_table[i].arrayname) {
312 u = utf_new_char(primitivetype_table[i].arrayname);
313 c = class_create_classinfo(u);
314 c = load_newly_created_array(c, NULL);
318 primitivetype_table[i].arrayclass = c;
325 primitivetype_table[i].arrayvftbl = c->vftbl;
333 /* link_class ******************************************************************
335 Wrapper function for link_class_intern to ease monitor enter/exit
336 and exception handling.
338 *******************************************************************************/
340 classinfo *link_class(classinfo *c)
345 *exceptionptr = new_nullpointerexception();
349 #if defined(USE_THREADS)
350 /* enter a monitor on the class */
352 builtin_monitorenter((java_objectheader *) c);
355 /* maybe the class is already linked */
357 #if defined(USE_THREADS)
358 builtin_monitorexit((java_objectheader *) c);
364 #if defined(STATISTICS)
367 if (getcompilingtime)
368 compilingtime_stop();
374 /* call the internal function */
376 r = link_class_intern(c);
378 /* if return value is NULL, we had a problem and the class is not linked */
383 #if defined(STATISTICS)
389 if (getcompilingtime)
390 compilingtime_start();
393 #if defined(USE_THREADS)
394 /* leave the monitor */
396 builtin_monitorexit((java_objectheader *) c);
403 /* link_class_intern ***********************************************************
405 Tries to link a class. The function calculates the length in bytes
406 that an instance of this class requires as well as the VTBL for
407 methods and interface methods.
409 *******************************************************************************/
411 static classinfo *link_class_intern(classinfo *c)
413 classinfo *super; /* super class */
414 classinfo *tc; /* temporary class variable */
415 s4 supervftbllength; /* vftbllegnth of super class */
416 s4 vftbllength; /* vftbllength of current class */
417 s4 interfacetablelength; /* interface table length */
418 vftbl_t *v; /* vftbl of current class */
419 s4 i,j; /* interface/method/field counter */
420 arraydescriptor *arraydesc; /* descriptor for array classes */
422 /* maybe the class is already linked */
428 log_message_class("Linking class: ", c);
430 /* the class must be loaded */
433 throw_cacao_exception_exit(string_java_lang_InternalError,
434 "Trying to link unloaded class");
436 /* ok, this class is somewhat linked */
442 /* check interfaces */
444 for (i = 0; i < c->interfacescount; i++) {
445 /* resolve this super interface */
447 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
451 c->interfaces[i].cls = tc;
453 /* detect circularity */
457 new_exception_utfmessage(string_java_lang_ClassCircularityError,
464 if (!(tc->flags & ACC_INTERFACE)) {
466 new_exception_message(string_java_lang_IncompatibleClassChangeError,
467 "Implementing class");
476 /* check super class */
480 if (c->super.any == NULL) { /* class java.lang.Object */
482 c->classUsed = USED; /* Object class is always used CO-RT*/
484 c->instancesize = sizeof(java_objectheader);
486 vftbllength = supervftbllength = 0;
491 /* resolve super class */
493 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
496 c->super.cls = super;
498 /* detect circularity */
502 new_exception_utfmessage(string_java_lang_ClassCircularityError,
507 assert(super->loaded);
509 if (super->flags & ACC_INTERFACE) {
510 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
511 log_text("Interface specified as super class");
515 /* Don't allow extending final classes */
517 if (super->flags & ACC_FINAL) {
519 new_exception_message(string_java_lang_VerifyError,
520 "Cannot inherit from final class");
525 if (!link_class(super))
528 /* handle array classes */
530 if (c->name->text[0] == '[')
531 if (!(arraydesc = link_array(c)))
534 if (c->flags & ACC_INTERFACE)
535 c->index = interfaceindex++;
537 c->index = super->index + 1;
539 c->instancesize = super->instancesize;
541 vftbllength = supervftbllength = super->vftbl->vftbllength;
543 c->finalizer = super->finalizer;
547 /* compute vftbl length */
549 for (i = 0; i < c->methodscount; i++) {
550 methodinfo *m = &(c->methods[i]);
552 if (!(m->flags & ACC_STATIC)) { /* is instance method */
558 for (j = 0; j < tc->methodscount; j++) {
559 if (method_canoverwrite(m, &(tc->methods[j]))) {
560 if (tc->methods[j].flags & ACC_PRIVATE)
561 goto notfoundvftblindex;
563 if (tc->methods[j].flags & ACC_FINAL) {
564 /* class a overrides final method . */
566 new_exception(string_java_lang_VerifyError);
570 m->vftblindex = tc->methods[j].vftblindex;
571 goto foundvftblindex;
579 m->vftblindex = (vftbllength++);
586 /* check interfaces of ABSTRACT class for unimplemented methods */
588 if (c->flags & ACC_ABSTRACT) {
591 s4 abstractmethodscount;
595 abstractmethodscount = 0;
597 for (i = 0; i < c->interfacescount; i++) {
598 ic = c->interfaces[i].cls;
600 for (j = 0; j < ic->methodscount; j++) {
601 im = &(ic->methods[j]);
603 /* skip `<clinit>' and `<init>' */
605 if (im->name == utf_clinit || im->name == utf_init)
611 for (k = 0; k < tc->methodscount; k++) {
612 if (method_canoverwrite(im, &(tc->methods[k])))
613 goto noabstractmethod;
619 abstractmethodscount++;
626 if (abstractmethodscount > 0) {
629 /* reallocate methods memory */
631 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
632 c->methodscount + abstractmethodscount);
634 for (i = 0; i < c->interfacescount; i++) {
635 ic = c->interfaces[i].cls;
637 for (j = 0; j < ic->methodscount; j++) {
638 im = &(ic->methods[j]);
640 /* skip `<clinit>' and `<init>' */
642 if (im->name == utf_clinit || im->name == utf_init)
648 for (k = 0; k < tc->methodscount; k++) {
649 if (method_canoverwrite(im, &(tc->methods[k])))
650 goto noabstractmethod2;
656 am = &(c->methods[c->methodscount]);
659 MCOPY(am, im, methodinfo, 1);
661 am->vftblindex = (vftbllength++);
672 #if defined(STATISTICS)
675 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
678 /* compute interfacetable length */
680 interfacetablelength = 0;
683 for (i = 0; i < tc->interfacescount; i++) {
684 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
685 if (h > interfacetablelength)
686 interfacetablelength = h;
691 /* allocate virtual function table */
693 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
694 sizeof(methodptr) * (vftbllength - 1) +
695 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
696 v = (vftbl_t *) (((methodptr *) v) +
697 (interfacetablelength - 1) * (interfacetablelength > 1));
698 c->header.vftbl = c->vftbl = v;
700 v->vftbllength = vftbllength;
701 v->interfacetablelength = interfacetablelength;
702 v->arraydesc = arraydesc;
704 /* store interface index in vftbl */
706 if (c->flags & ACC_INTERFACE)
707 v->baseval = -(c->index);
709 /* copy virtual function table of super class */
711 for (i = 0; i < supervftbllength; i++)
712 v->table[i] = super->vftbl->table[i];
714 /* add method stubs into virtual function table */
716 for (i = 0; i < c->methodscount; i++) {
717 methodinfo *m = &(c->methods[i]);
719 /* Methods in ABSTRACT classes from interfaces maybe already have a */
723 m->stubroutine = createcompilerstub(m);
725 if (!(m->flags & ACC_STATIC))
726 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
729 /* compute instance size and offset of each field */
731 for (i = 0; i < c->fieldscount; i++) {
733 fieldinfo *f = &(c->fields[i]);
735 if (!(f->flags & ACC_STATIC)) {
736 dsize = desc_typesize(f->descriptor);
737 c->instancesize = ALIGN(c->instancesize, dsize);
738 f->offset = c->instancesize;
739 c->instancesize += dsize;
743 /* initialize interfacetable and interfacevftbllength */
745 v->interfacevftbllength = MNEW(s4, interfacetablelength);
747 #if defined(STATISTICS)
749 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
752 for (i = 0; i < interfacetablelength; i++) {
753 v->interfacevftbllength[i] = 0;
754 v->interfacetable[-i] = NULL;
759 for (tc = c; tc != NULL; tc = tc->super.cls)
760 for (i = 0; i < tc->interfacescount; i++)
761 linker_addinterface(c, tc->interfaces[i].cls);
763 /* add finalizer method (not for java.lang.Object) */
768 fi = class_findmethod(c, utf_finalize, utf_void__void);
771 if (!(fi->flags & ACC_STATIC))
775 /* resolve exception class references */
777 for (i = 0; i < c->methodscount; i++) {
778 methodinfo *m = &(c->methods[i]);
780 for (j = 0; j < m->exceptiontablelength; j++) {
781 if (!m->exceptiontable[j].catchtype.any)
783 if (!resolve_classref_or_classinfo(NULL,
784 m->exceptiontable[j].catchtype,
785 resolveEager, true, false,
786 &(m->exceptiontable[j].catchtype.cls)))
790 for (j = 0; j < m->thrownexceptionscount; j++)
791 if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[j],
792 resolveEager, true, false,
793 &(m->thrownexceptions[j].cls)))
799 linker_compute_subclasses(c);
802 log_message_class("Linking done class: ", c);
804 /* just return c to show that we didn't had a problem */
810 /* link_array ******************************************************************
812 This function is called by link_class to create the arraydescriptor
815 This function returns NULL if the array cannot be linked because
816 the component type has not been linked yet.
818 *******************************************************************************/
820 static arraydescriptor *link_array(classinfo *c)
824 arraydescriptor *desc;
829 namelen = c->name->blength;
831 /* Check the component type */
833 switch (c->name->text[1]) {
835 /* c is an array of arrays. */
836 u = utf_new_intern(c->name->text + 1, namelen - 1);
837 if (!(comp = load_class_from_classloader(u, c->classloader)))
842 /* c is an array of objects. */
843 u = utf_new_intern(c->name->text + 2, namelen - 3);
844 if (!(comp = load_class_from_classloader(u, c->classloader)))
849 /* If the component type has not been linked, link it now */
850 assert(!comp || comp->loaded);
851 if (comp && !comp->linked) {
853 if (!link_class(comp))
857 /* Allocate the arraydescriptor */
858 desc = NEW(arraydescriptor);
861 /* c is an array of references */
862 desc->arraytype = ARRAYTYPE_OBJECT;
863 desc->componentsize = sizeof(void*);
864 desc->dataoffset = OFFSET(java_objectarray, data);
866 compvftbl = comp->vftbl;
869 log_text("Component class has no vftbl");
873 desc->componentvftbl = compvftbl;
875 if (compvftbl->arraydesc) {
876 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
878 if (compvftbl->arraydesc->dimension >= 255) {
879 log_text("Creating array of dimension >255");
883 desc->dimension = compvftbl->arraydesc->dimension + 1;
884 desc->elementtype = compvftbl->arraydesc->elementtype;
887 desc->elementvftbl = compvftbl;
889 desc->elementtype = ARRAYTYPE_OBJECT;
893 /* c is an array of a primitive type */
894 switch (c->name->text[1]) {
896 desc->arraytype = ARRAYTYPE_BOOLEAN;
897 desc->dataoffset = OFFSET(java_booleanarray,data);
898 desc->componentsize = sizeof(u1);
902 desc->arraytype = ARRAYTYPE_BYTE;
903 desc->dataoffset = OFFSET(java_bytearray,data);
904 desc->componentsize = sizeof(u1);
908 desc->arraytype = ARRAYTYPE_CHAR;
909 desc->dataoffset = OFFSET(java_chararray,data);
910 desc->componentsize = sizeof(u2);
914 desc->arraytype = ARRAYTYPE_DOUBLE;
915 desc->dataoffset = OFFSET(java_doublearray,data);
916 desc->componentsize = sizeof(double);
920 desc->arraytype = ARRAYTYPE_FLOAT;
921 desc->dataoffset = OFFSET(java_floatarray,data);
922 desc->componentsize = sizeof(float);
926 desc->arraytype = ARRAYTYPE_INT;
927 desc->dataoffset = OFFSET(java_intarray,data);
928 desc->componentsize = sizeof(s4);
932 desc->arraytype = ARRAYTYPE_LONG;
933 desc->dataoffset = OFFSET(java_longarray,data);
934 desc->componentsize = sizeof(s8);
938 desc->arraytype = ARRAYTYPE_SHORT;
939 desc->dataoffset = OFFSET(java_shortarray,data);
940 desc->componentsize = sizeof(s2);
944 *exceptionptr = new_classnotfoundexception(c->name);
948 desc->componentvftbl = NULL;
949 desc->elementvftbl = NULL;
951 desc->elementtype = desc->arraytype;
958 /* linker_compute_subclasses ***************************************************
962 *******************************************************************************/
964 static void linker_compute_subclasses(classinfo *c)
966 #if defined(USE_THREADS)
967 #if defined(NATIVE_THREADS)
974 if (!(c->flags & ACC_INTERFACE)) {
979 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
980 c->nextsub = c->super.cls->sub;
981 c->super.cls->sub = c;
986 /* compute class values */
988 linker_compute_class_values(class_java_lang_Object);
990 #if defined(USE_THREADS)
991 #if defined(NATIVE_THREADS)
1000 /* linker_compute_class_values *************************************************
1004 *******************************************************************************/
1006 static void linker_compute_class_values(classinfo *c)
1010 c->vftbl->baseval = ++classvalue;
1015 linker_compute_class_values(subs);
1017 subs = subs->nextsub;
1020 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1024 /* linker_addinterface *********************************************************
1026 Is needed by link_class for adding a VTBL to a class. All
1027 interfaces implemented by ic are added as well.
1029 *******************************************************************************/
1031 static void linker_addinterface(classinfo *c, classinfo *ic)
1035 vftbl_t *v = c->vftbl;
1037 if (i >= v->interfacetablelength) {
1038 log_text("Inernal error: interfacetable overflow");
1042 if (v->interfacetable[-i])
1045 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1046 v->interfacevftbllength[i] = 1;
1047 v->interfacetable[-i] = MNEW(methodptr, 1);
1048 v->interfacetable[-i][0] = NULL;
1051 v->interfacevftbllength[i] = ic->methodscount;
1052 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1054 #if defined(STATISTICS)
1056 count_vftbl_len += sizeof(methodptr) *
1057 (ic->methodscount + (ic->methodscount == 0));
1060 for (j = 0; j < ic->methodscount; j++) {
1064 for (m = 0; m < sc->methodscount; m++) {
1065 methodinfo *mi = &(sc->methods[m]);
1067 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1068 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1079 for (j = 0; j < ic->interfacescount; j++)
1080 linker_addinterface(c, ic->interfaces[j].cls);
1084 /* class_highestinterface ******************************************************
1086 Used by the function link_class to determine the amount of memory
1087 needed for the interface table.
1089 *******************************************************************************/
1091 static s4 class_highestinterface(classinfo *c)
1097 /* check for ACC_INTERFACE bit already done in link_class_intern */
1101 for (i = 0; i < c->interfacescount; i++) {
1102 h2 = class_highestinterface(c->interfaces[i].cls);
1113 * These are local overrides for various environment variables in Emacs.
1114 * Please do not remove this and leave it at the end of the file, where
1115 * Emacs will automagically detect them.
1116 * ---------------------------------------------------------------------
1119 * indent-tabs-mode: t