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 2200 2005-04-03 21:44:19Z twisti $
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46 #include "vm/loader.h"
47 #include "vm/options.h"
48 #include "vm/resolve.h"
49 #include "vm/statistics.h"
50 #include "vm/jit/codegen.inc.h"
53 /* global variables ***********************************************************/
55 static s4 interfaceindex; /* sequential numbering of interfaces */
59 /* primitivetype_table *********************************************************
61 Structure for primitive classes: contains the class for wrapping
62 the primitive type, the primitive class, the name of the class for
63 wrapping, the one character type signature and the name of the
66 CAUTION: Don't change the order of the types. This table is indexed
67 by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
69 *******************************************************************************/
71 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
72 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
73 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
74 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
75 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
76 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
77 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
78 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
79 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
80 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
81 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
82 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
86 /* private functions **********************************************************/
88 static bool link_primitivetype_table(void);
89 static classinfo *link_class_intern(classinfo *c);
90 static arraydescriptor *link_array(classinfo *c);
91 static void linker_compute_class_values(classinfo *c);
92 static void linker_compute_subclasses(classinfo *c);
93 static void linker_addinterface(classinfo *c, classinfo *ic);
94 static s4 class_highestinterface(classinfo *c);
97 /* linker_init *****************************************************************
99 Initializes the linker subsystem.
101 *******************************************************************************/
103 bool linker_init(void)
105 /* reset interface index */
109 /* link important system classes */
111 if (!link_class(class_java_lang_Object))
114 if (!link_class(class_java_lang_String))
117 if (!link_class(class_java_lang_Cloneable))
120 if (!link_class(class_java_io_Serializable))
124 /* link classes for wrapping primitive types */
126 if (!link_class(class_java_lang_Void))
129 if (!link_class(class_java_lang_Boolean))
132 if (!link_class(class_java_lang_Byte))
135 if (!link_class(class_java_lang_Character))
138 if (!link_class(class_java_lang_Short))
141 if (!link_class(class_java_lang_Integer))
144 if (!link_class(class_java_lang_Long))
147 if (!link_class(class_java_lang_Float))
150 if (!link_class(class_java_lang_Double))
154 /* create pseudo classes used by the typechecker */
156 /* pseudo class for Arraystubs (extends java.lang.Object) */
158 pseudo_class_Arraystub =
159 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
160 pseudo_class_Arraystub->loaded = true;
161 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
162 pseudo_class_Arraystub->interfacescount = 2;
163 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
164 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
165 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
166 if (!classcache_store(NULL, pseudo_class_Arraystub))
167 panic("could not cache pseudo_class_Arraystub");
169 if (!link_class(pseudo_class_Arraystub))
172 /* pseudo class representing the null type */
174 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
175 pseudo_class_Null->loaded = true;
176 pseudo_class_Null->super.cls = class_java_lang_Object;
177 if (!classcache_store(NULL, pseudo_class_Null))
178 panic("could not cache pseudo_class_Null");
180 if (!link_class(pseudo_class_Null))
183 /* pseudo class representing new uninitialized objects */
185 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
186 pseudo_class_New->loaded = true;
187 pseudo_class_New->linked = true; /* XXX is this allright? */
188 pseudo_class_New->super.cls = class_java_lang_Object;
189 if (!classcache_store(NULL,pseudo_class_New))
190 panic("could not cache pseudo_class_New");
192 /* create classes representing primitive types */
194 if (!link_primitivetype_table())
198 /* Correct vftbl-entries (retarded loading and linking of class */
199 /* java/lang/String). */
201 stringtable_update();
207 /* link_primitivetype_table ****************************************************
209 Create classes representing primitive types.
211 *******************************************************************************/
213 static bool link_primitivetype_table(void)
218 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
220 if (!primitivetype_table[i].name)
223 /* create primitive class */
224 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
225 c->classUsed = NOTUSED; /* not used initially CO-RT */
228 /* prevent loader from loading primitive class */
230 if (!classcache_store(NULL,c)) {
231 log_text("Could not cache primitive class");
237 primitivetype_table[i].class_primitive = c;
239 /* create class for wrapping the primitive type */
240 if (!load_class_bootstrap(utf_new_char(primitivetype_table[i].wrapname),&c))
242 primitivetype_table[i].class_wrap = c;
243 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
244 primitivetype_table[i].class_wrap->impldBy = NULL;
246 /* create the primitive array class */
247 if (primitivetype_table[i].arrayname) {
248 c = class_create_classinfo(utf_new_char(primitivetype_table[i].arrayname));
249 if (!load_newly_created_array(c, NULL))
251 primitivetype_table[i].arrayclass = c;
256 primitivetype_table[i].arrayvftbl = c->vftbl;
264 /* link_class ******************************************************************
266 Wrapper function for link_class_intern to ease monitor enter/exit
267 and exception handling.
269 *******************************************************************************/
271 classinfo *link_class(classinfo *c)
276 *exceptionptr = new_nullpointerexception();
280 #if defined(USE_THREADS)
281 /* enter a monitor on the class */
283 builtin_monitorenter((java_objectheader *) c);
286 /* maybe the class is already linked */
288 #if defined(USE_THREADS)
289 builtin_monitorexit((java_objectheader *) c);
295 #if defined(STATISTICS)
298 if (getcompilingtime)
299 compilingtime_stop();
305 /* call the internal function */
306 r = link_class_intern(c);
308 /* if return value is NULL, we had a problem and the class is not linked */
312 #if defined(STATISTICS)
318 if (getcompilingtime)
319 compilingtime_start();
322 #if defined(USE_THREADS)
323 /* leave the monitor */
325 builtin_monitorexit((java_objectheader *) c);
332 /* link_class_intern ***********************************************************
334 Tries to link a class. The function calculates the length in bytes
335 that an instance of this class requires as well as the VTBL for
336 methods and interface methods.
338 *******************************************************************************/
340 static classinfo *link_class_intern(classinfo *c)
342 classinfo *super; /* super class */
343 classinfo *tc; /* temporary class variable */
344 s4 supervftbllength; /* vftbllegnth of super class */
345 s4 vftbllength; /* vftbllength of current class */
346 s4 interfacetablelength; /* interface table length */
347 vftbl_t *v; /* vftbl of current class */
348 s4 i,j; /* interface/method/field counter */
349 arraydescriptor *arraydesc; /* descriptor for array classes */
351 /* maybe the class is already linked */
356 log_message_class("Linking class: ", c);
358 /* the class must be loaded */
360 throw_cacao_exception_exit(string_java_lang_InternalError,
361 "Trying to link unloaded class");
363 /* ok, this class is somewhat linked */
368 /* check interfaces */
370 for (i = 0; i < c->interfacescount; i++) {
371 /* resolve this super interface */
372 if (!resolve_classref_or_classinfo(NULL,c->interfaces[i],resolveEager,false,&tc))
374 c->interfaces[i].cls = tc;
376 /* detect circularity */
380 new_exception_utfmessage(string_java_lang_ClassCircularityError,
387 if (!(tc->flags & ACC_INTERFACE)) {
389 new_exception_message(string_java_lang_IncompatibleClassChangeError,
390 "Implementing class");
399 /* check super class */
402 if (c->super.any == NULL) { /* class java.lang.Object */
404 c->classUsed = USED; /* Object class is always used CO-RT*/
406 c->instancesize = sizeof(java_objectheader);
408 vftbllength = supervftbllength = 0;
413 /* resolve super class */
414 if (!resolve_classref_or_classinfo(NULL,c->super,resolveEager,false,&super))
416 c->super.cls = super;
418 /* detect circularity */
421 new_exception_utfmessage(string_java_lang_ClassCircularityError,
426 assert(super->loaded);
428 if (super->flags & ACC_INTERFACE) {
429 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
430 panic("Interface specified as super class");
433 /* Don't allow extending final classes */
434 if (super->flags & ACC_FINAL) {
436 new_exception_message(string_java_lang_VerifyError,
437 "Cannot inherit from final class");
442 if (!link_class(super))
445 /* handle array classes */
446 if (c->name->text[0] == '[')
447 if (!(arraydesc = link_array(c)))
450 if (c->flags & ACC_INTERFACE)
451 c->index = interfaceindex++;
453 c->index = super->index + 1;
455 c->instancesize = super->instancesize;
457 vftbllength = supervftbllength = super->vftbl->vftbllength;
459 c->finalizer = super->finalizer;
463 /* compute vftbl length */
465 for (i = 0; i < c->methodscount; i++) {
466 methodinfo *m = &(c->methods[i]);
468 if (!(m->flags & ACC_STATIC)) { /* is instance method */
474 for (j = 0; j < tc->methodscount; j++) {
475 if (method_canoverwrite(m, &(tc->methods[j]))) {
476 if (tc->methods[j].flags & ACC_PRIVATE)
477 goto notfoundvftblindex;
479 if (tc->methods[j].flags & ACC_FINAL) {
480 /* class a overrides final method . */
482 new_exception(string_java_lang_VerifyError);
486 m->vftblindex = tc->methods[j].vftblindex;
487 goto foundvftblindex;
495 m->vftblindex = (vftbllength++);
502 /* check interfaces of ABSTRACT class for unimplemented methods */
504 if (c->flags & ACC_ABSTRACT) {
507 s4 abstractmethodscount;
511 abstractmethodscount = 0;
513 for (i = 0; i < c->interfacescount; i++) {
514 ic = c->interfaces[i].cls;
516 for (j = 0; j < ic->methodscount; j++) {
517 im = &(ic->methods[j]);
519 /* skip `<clinit>' and `<init>' */
521 if (im->name == utf_clinit || im->name == utf_init)
527 for (k = 0; k < tc->methodscount; k++) {
528 if (method_canoverwrite(im, &(tc->methods[k])))
529 goto noabstractmethod;
535 abstractmethodscount++;
542 if (abstractmethodscount > 0) {
545 /* reallocate methods memory */
547 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
548 c->methodscount + abstractmethodscount);
550 for (i = 0; i < c->interfacescount; i++) {
551 ic = c->interfaces[i].cls;
553 for (j = 0; j < ic->methodscount; j++) {
554 im = &(ic->methods[j]);
556 /* skip `<clinit>' and `<init>' */
558 if (im->name == utf_clinit || im->name == utf_init)
564 for (k = 0; k < tc->methodscount; k++) {
565 if (method_canoverwrite(im, &(tc->methods[k])))
566 goto noabstractmethod2;
572 am = &(c->methods[c->methodscount]);
575 MCOPY(am, im, methodinfo, 1);
577 am->vftblindex = (vftbllength++);
588 #if defined(STATISTICS)
591 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
594 /* compute interfacetable length */
596 interfacetablelength = 0;
599 for (i = 0; i < tc->interfacescount; i++) {
600 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
601 if (h > interfacetablelength)
602 interfacetablelength = h;
607 /* allocate virtual function table */
609 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
610 sizeof(methodptr) * (vftbllength - 1) +
611 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
612 v = (vftbl_t *) (((methodptr *) v) +
613 (interfacetablelength - 1) * (interfacetablelength > 1));
614 c->header.vftbl = c->vftbl = v;
616 v->vftbllength = vftbllength;
617 v->interfacetablelength = interfacetablelength;
618 v->arraydesc = arraydesc;
620 /* store interface index in vftbl */
622 if (c->flags & ACC_INTERFACE)
623 v->baseval = -(c->index);
625 /* copy virtual function table of super class */
627 for (i = 0; i < supervftbllength; i++)
628 v->table[i] = super->vftbl->table[i];
630 /* add method stubs into virtual function table */
632 for (i = 0; i < c->methodscount; i++) {
633 methodinfo *m = &(c->methods[i]);
635 /* Methods in ABSTRACT classes from interfaces maybe already have a */
638 if (!m->stubroutine) {
639 if (!(m->flags & ACC_NATIVE)) {
640 m->stubroutine = createcompilerstub(m);
643 functionptr f = native_findfunction(c->name,
646 (m->flags & ACC_STATIC));
647 #if defined(STATIC_CLASSPATH)
650 m->stubroutine = createnativestub(f, m);
654 if (!(m->flags & ACC_STATIC))
655 v->table[m->vftblindex] = m->stubroutine;
658 /* compute instance size and offset of each field */
660 for (i = 0; i < c->fieldscount; i++) {
662 fieldinfo *f = &(c->fields[i]);
664 if (!(f->flags & ACC_STATIC)) {
665 dsize = desc_typesize(f->descriptor);
666 c->instancesize = ALIGN(c->instancesize, dsize);
667 f->offset = c->instancesize;
668 c->instancesize += dsize;
672 /* initialize interfacetable and interfacevftbllength */
674 v->interfacevftbllength = MNEW(s4, interfacetablelength);
676 #if defined(STATISTICS)
678 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
681 for (i = 0; i < interfacetablelength; i++) {
682 v->interfacevftbllength[i] = 0;
683 v->interfacetable[-i] = NULL;
688 for (tc = c; tc != NULL; tc = tc->super.cls)
689 for (i = 0; i < tc->interfacescount; i++)
690 linker_addinterface(c, tc->interfaces[i].cls);
692 /* add finalizer method (not for java.lang.Object) */
697 fi = class_findmethod(c, utf_finalize, utf_void__void);
700 if (!(fi->flags & ACC_STATIC))
704 /* resolve exception class references */
706 for (i = 0; i < c->methodscount; i++) {
707 methodinfo *m = c->methods + i;
708 for (j=0; j<m->exceptiontablelength; ++j) {
709 if (!m->exceptiontable[j].catchtype.any)
711 if (!resolve_classref_or_classinfo(NULL,m->exceptiontable[j].catchtype,
712 resolveEager,false,&(m->exceptiontable[j].catchtype.cls)))
715 for (j=0; j<m->thrownexceptionscount; ++j)
716 if (!resolve_classref_or_classinfo(NULL,m->thrownexceptions[j],
717 resolveEager,false,&(m->thrownexceptions[j].cls)))
723 linker_compute_subclasses(c);
726 log_message_class("Linking done class: ", c);
728 /* just return c to show that we didn't had a problem */
734 /* link_array ******************************************************************
736 This function is called by link_class to create the arraydescriptor
739 This function returns NULL if the array cannot be linked because
740 the component type has not been linked yet.
742 *******************************************************************************/
744 static arraydescriptor *link_array(classinfo *c)
746 classinfo *comp = NULL;
747 s4 namelen = c->name->blength;
748 arraydescriptor *desc;
751 /* Check the component type */
752 switch (c->name->text[1]) {
754 /* c is an array of arrays. */
755 if (!load_class_from_classloader(utf_new_intern(c->name->text + 1, namelen - 1),
756 c->classloader,&comp))
761 /* c is an array of objects. */
762 if (!load_class_from_classloader(utf_new_intern(c->name->text + 2, namelen - 3),
763 c->classloader,&comp))
768 /* If the component type has not been linked, link it now */
769 assert(!comp || comp->loaded);
770 if (comp && !comp->linked) {
772 if (!link_class(comp))
776 /* Allocate the arraydescriptor */
777 desc = NEW(arraydescriptor);
780 /* c is an array of references */
781 desc->arraytype = ARRAYTYPE_OBJECT;
782 desc->componentsize = sizeof(void*);
783 desc->dataoffset = OFFSET(java_objectarray, data);
785 compvftbl = comp->vftbl;
787 panic("Component class has no vftbl");
788 desc->componentvftbl = compvftbl;
790 if (compvftbl->arraydesc) {
791 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
792 if (compvftbl->arraydesc->dimension >= 255)
793 panic("Creating array of dimension >255");
794 desc->dimension = compvftbl->arraydesc->dimension + 1;
795 desc->elementtype = compvftbl->arraydesc->elementtype;
798 desc->elementvftbl = compvftbl;
800 desc->elementtype = ARRAYTYPE_OBJECT;
804 /* c is an array of a primitive type */
805 switch (c->name->text[1]) {
807 desc->arraytype = ARRAYTYPE_BOOLEAN;
808 desc->dataoffset = OFFSET(java_booleanarray,data);
809 desc->componentsize = sizeof(u1);
813 desc->arraytype = ARRAYTYPE_BYTE;
814 desc->dataoffset = OFFSET(java_bytearray,data);
815 desc->componentsize = sizeof(u1);
819 desc->arraytype = ARRAYTYPE_CHAR;
820 desc->dataoffset = OFFSET(java_chararray,data);
821 desc->componentsize = sizeof(u2);
825 desc->arraytype = ARRAYTYPE_DOUBLE;
826 desc->dataoffset = OFFSET(java_doublearray,data);
827 desc->componentsize = sizeof(double);
831 desc->arraytype = ARRAYTYPE_FLOAT;
832 desc->dataoffset = OFFSET(java_floatarray,data);
833 desc->componentsize = sizeof(float);
837 desc->arraytype = ARRAYTYPE_INT;
838 desc->dataoffset = OFFSET(java_intarray,data);
839 desc->componentsize = sizeof(s4);
843 desc->arraytype = ARRAYTYPE_LONG;
844 desc->dataoffset = OFFSET(java_longarray,data);
845 desc->componentsize = sizeof(s8);
849 desc->arraytype = ARRAYTYPE_SHORT;
850 desc->dataoffset = OFFSET(java_shortarray,data);
851 desc->componentsize = sizeof(s2);
855 panic("Invalid array class name");
858 desc->componentvftbl = NULL;
859 desc->elementvftbl = NULL;
861 desc->elementtype = desc->arraytype;
868 /* linker_compute_subclasses ***************************************************
872 *******************************************************************************/
874 static void linker_compute_subclasses(classinfo *c)
876 #if defined(USE_THREADS)
877 #if defined(NATIVE_THREADS)
884 if (!(c->flags & ACC_INTERFACE)) {
889 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
890 c->nextsub = c->super.cls->sub;
891 c->super.cls->sub = c;
896 /* this is the java.lang.Object special case */
898 if (!class_java_lang_Object) {
899 linker_compute_class_values(c);
902 linker_compute_class_values(class_java_lang_Object);
905 #if defined(USE_THREADS)
906 #if defined(NATIVE_THREADS)
915 /* linker_compute_class_values *************************************************
919 *******************************************************************************/
921 static void linker_compute_class_values(classinfo *c)
925 c->vftbl->baseval = ++classvalue;
930 linker_compute_class_values(subs);
932 subs = subs->nextsub;
935 c->vftbl->diffval = classvalue - c->vftbl->baseval;
939 /* linker_addinterface *********************************************************
941 Is needed by link_class for adding a VTBL to a class. All
942 interfaces implemented by ic are added as well.
944 *******************************************************************************/
946 static void linker_addinterface(classinfo *c, classinfo *ic)
950 vftbl_t *v = c->vftbl;
952 if (i >= v->interfacetablelength)
953 panic ("Inernal error: interfacetable overflow");
955 if (v->interfacetable[-i])
958 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
959 v->interfacevftbllength[i] = 1;
960 v->interfacetable[-i] = MNEW(methodptr, 1);
961 v->interfacetable[-i][0] = NULL;
964 v->interfacevftbllength[i] = ic->methodscount;
965 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
967 #if defined(STATISTICS)
969 count_vftbl_len += sizeof(methodptr) *
970 (ic->methodscount + (ic->methodscount == 0));
973 for (j = 0; j < ic->methodscount; j++) {
977 for (m = 0; m < sc->methodscount; m++) {
978 methodinfo *mi = &(sc->methods[m]);
980 if (method_canoverwrite(mi, &(ic->methods[j]))) {
981 v->interfacetable[-i][j] = v->table[mi->vftblindex];
992 for (j = 0; j < ic->interfacescount; j++)
993 linker_addinterface(c, ic->interfaces[j].cls);
997 /* class_highestinterface ******************************************************
999 Used by the function link_class to determine the amount of memory
1000 needed for the interface table.
1002 *******************************************************************************/
1004 static s4 class_highestinterface(classinfo *c)
1010 /* check for ACC_INTERFACE bit already done in link_class_intern */
1014 for (i = 0; i < c->interfacescount; i++) {
1015 h2 = class_highestinterface(c->interfaces[i].cls);
1025 /***************** Function: print_arraydescriptor ****************************
1027 Debug helper for displaying an arraydescriptor
1029 *******************************************************************************/
1031 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
1034 fprintf(file, "<NULL>");
1039 if (desc->componentvftbl) {
1040 if (desc->componentvftbl->class)
1041 utf_fprint(file, desc->componentvftbl->class->name);
1043 fprintf(file, "<no classinfo>");
1049 if (desc->elementvftbl) {
1050 if (desc->elementvftbl->class)
1051 utf_fprint(file, desc->elementvftbl->class->name);
1053 fprintf(file, "<no classinfo>");
1057 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1058 desc->dataoffset, desc->componentsize);
1063 * These are local overrides for various environment variables in Emacs.
1064 * Please do not remove this and leave it at the end of the file, where
1065 * Emacs will automagically detect them.
1066 * ---------------------------------------------------------------------
1069 * indent-tabs-mode: t