* src/vm/jit/alpha/patcher.c (assert.h): Added.
[cacao.git] / src / vm / jit / alpha / patcher.c
1 /* src/vm/jit/alpha/patcher.c - Alpha code patching functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
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.
14
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.
19
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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 5094 2006-07-10 13:51:38Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "vm/types.h"
41
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "vm/builtin.h"
45 #include "vm/class.h"
46 #include "vm/exceptions.h"
47 #include "vm/field.h"
48 #include "vm/initialize.h"
49 #include "vm/options.h"
50 #include "vm/references.h"
51 #include "vm/resolve.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/patcher.h"
54 #include "vm/jit/methodheader.h"
55
56
57 /* patcher_wrapper *************************************************************
58
59    Wrapper for all patchers.  It also creates the stackframe info
60    structure.
61
62    If the return value of the patcher function is false, it gets the
63    exception object, clears the exception pointer and returns the
64    exception.
65
66 *******************************************************************************/
67
68 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
69 {
70         stackframeinfo     sfi;
71         u1                *xpc;
72         java_objectheader *o;
73         functionptr        f;
74         bool               result;
75         java_objectheader *e;
76
77         /* define the patcher function */
78
79         bool (*patcher_function)(u1 *);
80
81         assert(pv != NULL);
82
83         /* get stuff from the stack */
84
85         xpc = (u1 *)                *((ptrint *) (sp + 5 * 8));
86         o   = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
87         f   = (functionptr)         *((ptrint *) (sp + 0 * 8));
88
89         /* store PV into the patcher function position */
90
91         *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
92
93         /* cast the passed function to a patcher function */
94
95         patcher_function = (bool (*)(u1 *)) (ptrint) f;
96
97         /* enter a monitor on the patching position */
98
99         PATCHER_MONITORENTER;
100
101         /* create the stackframeinfo */
102
103         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, ra, xpc);
104
105         /* call the proper patcher function */
106
107         result = (patcher_function)(sp);
108
109         /* remove the stackframeinfo */
110
111         stacktrace_remove_stackframeinfo(&sfi);
112
113         /* check for return value and exit accordingly */
114
115         if (result == false) {
116                 e = exceptions_get_and_clear_exception();
117
118                 PATCHER_MONITOREXIT;
119
120                 return e;
121         }
122
123         PATCHER_MARK_PATCHED_MONITOREXIT;
124
125         return NULL;
126 }
127
128
129 /* patcher_get_putstatic *******************************************************
130
131    Machine code:
132
133    <patched call position>
134    a73bff98    ldq     t11,-104(pv)
135    a2590000    ldl     a2,0(t11)
136
137 *******************************************************************************/
138
139 bool patcher_get_putstatic(u1 *sp)
140 {
141         u1               *ra;
142         u4                mcode;
143         unresolved_field *uf;
144         s4                disp;
145         u1               *pv;
146         fieldinfo        *fi;
147
148         /* get stuff from the stack */
149
150         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
151         mcode =                       *((u4 *)     (sp + 3 * 8));
152         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 8));
153         disp  =                       *((s4 *)     (sp + 1 * 8));
154         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
155
156         /* calculate and set the new return address */
157
158         ra = ra - 1 * 4;
159         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
160
161         /* get the fieldinfo */
162
163         if (!(fi = resolve_field_eager(uf)))
164                 return false;
165
166         /* check if the field's class is initialized */
167
168         if (!(fi->class->state & CLASS_INITIALIZED))
169                 if (!initialize_class(fi->class))
170                         return false;
171
172         /* patch back original code */
173
174         *((u4 *) ra) = mcode;
175
176         /* synchronize instruction cache */
177
178         md_icacheflush(NULL, 0);
179
180         /* patch the field value's address */
181
182         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
183
184         return true;
185 }
186
187
188 /* patcher_get_putfield ********************************************************
189
190    Machine code:
191
192    <patched call position>
193    a2af0020    ldl     a5,32(s6)
194
195 *******************************************************************************/
196
197 bool patcher_get_putfield(u1 *sp)
198 {
199         u1               *ra;
200         u4                mcode;
201         unresolved_field *uf;
202         fieldinfo        *fi;
203
204         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
205         mcode =                       *((u4 *)     (sp + 3 * 8));
206         uf    = (unresolved_field *)  *((ptrint *) (sp + 2 * 8));
207
208         /* calculate and set the new return address */
209
210         ra = ra - 1 * 4;
211         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
212
213         /* get the fieldinfo */
214
215         if (!(fi = resolve_field_eager(uf)))
216                 return false;
217
218         /* patch back original code */
219
220         *((u4 *) ra) = mcode;
221
222         /* if we show disassembly, we have to skip the nop */
223
224         if (opt_showdisassemble)
225                 ra = ra + 4;
226
227         /* patch the field's offset */
228
229         *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
230
231         /* synchronize instruction cache */
232
233         md_icacheflush(NULL, 0);
234
235         return true;
236 }
237
238
239 /* patcher_aconst **************************************************************
240
241    Machine code:
242
243    <patched call postition>
244    a61bff80    ldq     a0,-128(pv)
245
246 *******************************************************************************/
247
248 bool patcher_aconst(u1 *sp)
249 {
250         u1                *ra;
251         u4                 mcode;
252         constant_classref *cr;
253         s4                 disp;
254         u1                *pv;
255         classinfo         *c;
256
257         /* get stuff from the stack */
258
259         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
260         mcode =                       *((u4 *)     (sp + 3 * 8));
261         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
262         disp  =                       *((s4 *)     (sp + 1 * 8));
263         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
264
265         /* calculate and set the new return address */
266
267         ra = ra - 1 * 4;
268         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
269
270         /* get the classinfo */
271
272         if (!(c = resolve_classref_eager(cr)))
273                 return false;
274
275         /* patch back original code */
276
277         *((u4 *) ra) = mcode;
278
279         /* synchronize instruction cache */
280
281         md_icacheflush(NULL, 0);
282
283         /* patch the classinfo pointer */
284
285         *((ptrint *) (pv + disp)) = (ptrint) c;
286
287         return true;
288 }
289
290
291 /* patcher_builtin_multianewarray **********************************************
292
293    Machine code:
294
295    <patched call position>
296    a63bff80    ldq     a1,-128(pv)
297    47de0412    mov     sp,a2
298    a77bff78    ldq     pv,-136(pv)
299    6b5b4000    jsr     (pv)
300
301 *******************************************************************************/
302
303 bool patcher_builtin_multianewarray(u1 *sp)
304 {
305         u1                *ra;
306         u4                 mcode;
307         constant_classref *cr;
308         s4                 disp;
309         u1                *pv;
310         classinfo         *c;
311
312         /* get stuff from the stack */
313
314         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
315         mcode =                       *((u4 *)     (sp + 3 * 8));
316         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
317         disp  =                       *((s4 *)     (sp + 1 * 8));
318         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
319
320         /* calculate and set the new return address */
321
322         ra = ra - 1 * 4;
323         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
324
325         /* get the classinfo */
326
327         if (!(c = resolve_classref_eager(cr)))
328                 return false;
329
330         /* patch back original code */
331
332         *((u4 *) ra) = mcode;
333
334         /* synchronize instruction cache */
335
336         md_icacheflush(NULL, 0);
337
338         /* patch the classinfo pointer */
339
340         *((ptrint *) (pv + disp)) = (ptrint) c;
341
342         return true;
343 }
344
345
346 /* patcher_builtin_arraycheckcast **********************************************
347
348    Machine code:
349
350    <patched call position>
351    a63bfe60    ldq     a1,-416(pv)
352    a77bfe58    ldq     pv,-424(pv)
353    6b5b4000    jsr     (pv)
354
355 *******************************************************************************/
356
357 bool patcher_builtin_arraycheckcast(u1 *sp)
358 {
359         u1                *ra;
360         u4                 mcode;
361         constant_classref *cr;
362         s4                 disp;
363         u1                *pv;
364         classinfo         *c;
365
366         /* get stuff from the stack */
367
368         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
369         mcode =                       *((u4 *)     (sp + 3 * 8));
370         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
371         disp  =                       *((s4 *)     (sp + 1 * 8));
372         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
373
374         /* calculate and set the new return address */
375
376         ra = ra - 1 * 4;
377         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
378
379         /* get the classinfo */
380
381         if (!(c = resolve_classref_eager(cr)))
382                 return false;
383
384         /* patch back original code */
385
386         *((u4 *) ra) = mcode;
387
388         /* synchronize instruction cache */
389
390         md_icacheflush(NULL, 0);
391
392         /* patch the classinfo pointer */
393
394         *((ptrint *) (pv + disp)) = (ptrint) c;
395
396         return true;
397 }
398
399
400 /* patcher_invokestatic_special ************************************************
401
402    Machine code:
403
404    <patched call position>
405    a77bffa8    ldq     pv,-88(pv)
406    6b5b4000    jsr     (pv)
407
408 ******************************************************************************/
409
410 bool patcher_invokestatic_special(u1 *sp)
411 {
412         u1                *ra;
413         u4                 mcode;
414         unresolved_method *um;
415         s4                 disp;
416         u1                *pv;
417         methodinfo        *m;
418
419         /* get stuff from the stack */
420
421         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
422         mcode =                       *((u4 *)     (sp + 3 * 8));
423         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
424         disp  =                       *((s4 *)     (sp + 1 * 8));
425         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
426
427         /* calculate and set the new return address */
428
429         ra = ra - 1 * 4;
430         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
431
432         /* get the fieldinfo */
433
434         if (!(m = resolve_method_eager(um)))
435                 return false;
436
437         /* patch back original code */
438
439         *((u4 *) ra) = mcode;
440
441         /* synchronize instruction cache */
442
443         md_icacheflush(NULL, 0);
444
445         /* patch stubroutine */
446
447         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
448
449         return true;
450 }
451
452
453 /* patcher_invokevirtual *******************************************************
454
455    Machine code:
456
457    <patched call position>
458    a7900000    ldq     at,0(a0)
459    a77c0100    ldq     pv,256(at)
460    6b5b4000    jsr     (pv)
461
462 *******************************************************************************/
463
464 bool patcher_invokevirtual(u1 *sp)
465 {
466         u1                *ra;
467         u4                 mcode;
468         unresolved_method *um;
469         methodinfo        *m;
470
471         /* get stuff from the stack */
472
473         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
474         mcode =                       *((u4 *)     (sp + 3 * 8));
475         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
476
477         /* calculate and set the new return address */
478
479         ra = ra - 1 * 4;
480         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
481
482         /* get the fieldinfo */
483
484         if (!(m = resolve_method_eager(um)))
485                 return false;
486
487         /* patch back original code */
488
489         *((u4 *) ra) = mcode;
490
491         /* if we show disassembly, we have to skip the nop */
492
493         if (opt_showdisassemble)
494                 ra = ra + 4;
495
496         /* patch vftbl index */
497
498         *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
499                                                                  sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
500
501         /* synchronize instruction cache */
502
503         md_icacheflush(NULL, 0);
504
505         return true;
506 }
507
508
509 /* patcher_invokeinterface *****************************************************
510
511    Machine code:
512
513    <patched call position>
514    a7900000    ldq     at,0(a0)
515    a79cffa0    ldq     at,-96(at)
516    a77c0018    ldq     pv,24(at)
517    6b5b4000    jsr     (pv)
518
519 *******************************************************************************/
520
521 bool patcher_invokeinterface(u1 *sp)
522 {
523         u1                *ra;
524         u4                 mcode;
525         unresolved_method *um;
526         methodinfo        *m;
527
528         /* get stuff from the stack */
529
530         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
531         mcode =                       *((u4 *)     (sp + 3 * 8));
532         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
533
534         /* calculate and set the new return address */
535
536         ra = ra - 1 * 4;
537         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
538
539         /* get the fieldinfo */
540
541         if (!(m = resolve_method_eager(um)))
542                 return false;
543
544         /* patch back original code */
545
546         *((u4 *) ra) = mcode;
547
548         /* if we show disassembly, we have to skip the nop */
549
550         if (opt_showdisassemble)
551                 ra = ra + 4;
552
553         /* patch interfacetable index */
554
555         *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
556                                                                  sizeof(methodptr*) * m->class->index) & 0x0000ffff);
557
558         /* patch method offset */
559
560         *((s4 *) (ra + 4 + 4)) |=
561                 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
562
563         /* synchronize instruction cache */
564
565         md_icacheflush(NULL, 0);
566
567         return true;
568 }
569
570
571 /* patcher_checkcast_instanceof_flags ******************************************
572
573    Machine code:
574
575    <patched call position>
576
577 *******************************************************************************/
578
579 bool patcher_checkcast_instanceof_flags(u1 *sp)
580 {
581         u1                *ra;
582         u4                 mcode;
583         constant_classref *cr;
584         s4                 disp;
585         u1                *pv;
586         classinfo         *c;
587
588         /* get stuff from the stack */
589
590         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
591         mcode =                       *((u4 *)     (sp + 3 * 8));
592         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
593         disp  =                       *((s4 *)     (sp + 1 * 8));
594         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
595
596         /* calculate and set the new return address */
597
598         ra = ra - 1 * 4;
599         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
600
601         /* get the fieldinfo */
602
603         if (!(c = resolve_classref_eager(cr)))
604                 return false;
605
606         /* patch back original code */
607
608         *((u4 *) ra) = mcode;
609
610         /* synchronize instruction cache */
611
612         md_icacheflush(NULL, 0);
613
614         /* patch class flags */
615
616         *((s4 *) (pv + disp)) = (s4) c->flags;
617
618         return true;
619 }
620
621
622 /* patcher_checkcast_instanceof_interface **************************************
623
624    Machine code:
625
626    <patched call position>
627    a78e0000    ldq     at,0(s5)
628    a3bc001c    ldl     gp,28(at)
629    23bdfffd    lda     gp,-3(gp)
630    efa0002e    ble     gp,0x00000200002bf6b0
631    a7bcffe8    ldq     gp,-24(at)
632
633 *******************************************************************************/
634
635 bool patcher_checkcast_instanceof_interface(u1 *sp)
636 {
637         u1                *ra;
638         u4                 mcode;
639         constant_classref *cr;
640         classinfo         *c;
641
642         /* get stuff from the stack */
643
644         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
645         mcode =                       *((u4 *)     (sp + 3 * 8));
646         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
647
648         /* calculate and set the new return address */
649
650         ra = ra - 1 * 4;
651         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
652
653         /* get the fieldinfo */
654
655         if (!(c = resolve_classref_eager(cr)))
656                 return false;
657
658         /* patch back original code */
659
660         *((u4 *) ra) = mcode;
661
662         /* if we show disassembly, we have to skip the nop */
663
664         if (opt_showdisassemble)
665                 ra = ra + 4;
666
667         /* patch super class index */
668
669         *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
670
671         *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
672                                                                          c->index * sizeof(methodptr*)) & 0x0000ffff);
673
674         /* synchronize instruction cache */
675
676         md_icacheflush(NULL, 0);
677
678         return true;
679 }
680
681
682 /* patcher_checkcast_instanceof_class ******************************************
683
684    Machine code:
685
686    <patched call position>
687    a7940000    ldq     at,0(a4)
688    a7bbff28    ldq     gp,-216(pv)
689
690 *******************************************************************************/
691
692 bool patcher_checkcast_instanceof_class(u1 *sp)
693 {
694         u1                *ra;
695         u4                 mcode;
696         constant_classref *cr;
697         s4                 disp;
698         u1                *pv;
699         classinfo         *c;
700
701         /* get stuff from the stack */
702
703         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
704         mcode =                       *((u4 *)     (sp + 3 * 8));
705         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
706         disp  =                       *((s4 *)     (sp + 1 * 8));
707         pv    = (u1 *)                *((ptrint *) (sp + 0 * 8));
708
709         /* calculate and set the new return address */
710
711         ra = ra - 1 * 4;
712         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
713
714         /* get the fieldinfo */
715
716         if (!(c = resolve_classref_eager(cr)))
717                 return false;
718
719         /* patch back original code */
720
721         *((u4 *) ra) = mcode;
722
723         /* synchronize instruction cache */
724
725         md_icacheflush(NULL, 0);
726
727         /* patch super class' vftbl */
728
729         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
730
731         return true;
732 }
733
734
735 /* patcher_clinit **************************************************************
736
737    XXX
738
739 *******************************************************************************/
740
741 bool patcher_clinit(u1 *sp)
742 {
743         u1                *ra;
744         u4                 mcode;
745         classinfo         *c;
746
747         /* get stuff from the stack */
748
749         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
750         mcode =                       *((u4 *)     (sp + 3 * 8));
751         c     = (classinfo *)         *((ptrint *) (sp + 2 * 8));
752
753         /* calculate and set the new return address */
754
755         ra = ra - 1 * 4;
756         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
757
758         /* check if the class is initialized */
759
760         if (!(c->state & CLASS_INITIALIZED))
761                 if (!initialize_class(c))
762                         return false;
763
764         /* patch back original code */
765
766         *((u4 *) ra) = mcode;
767
768         /* synchronize instruction cache */
769
770         md_icacheflush(NULL, 0);
771
772         return true;
773 }
774
775
776 /* patcher_athrow_areturn ******************************************************
777
778    Machine code:
779
780    <patched call position>
781
782 *******************************************************************************/
783
784 #ifdef ENABLE_VERIFIER
785 bool patcher_athrow_areturn(u1 *sp)
786 {
787         u1               *ra;
788         u4                mcode;
789         unresolved_class *uc;
790         classinfo        *c;
791
792         /* get stuff from the stack */
793
794         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
795         mcode =                       *((u4 *)     (sp + 3 * 8));
796         uc    = (unresolved_class *)  *((ptrint *) (sp + 2 * 8));
797
798         /* calculate and set the new return address */
799
800         ra = ra - 1 * 4;
801         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
802
803         /* resolve the class */
804
805         if (!resolve_class(uc, resolveEager, false, &c))
806                 return false;
807
808         /* patch back original code */
809
810         *((u4 *) ra) = mcode;
811
812         /* synchronize instruction cache */
813
814         md_icacheflush(NULL, 0);
815
816         return true;
817 }
818 #endif /* ENABLE_VERIFIER */
819
820
821 /* patcher_resolve_native ******************************************************
822
823    XXX
824
825 *******************************************************************************/
826
827 #if !defined(WITH_STATIC_CLASSPATH)
828 bool patcher_resolve_native(u1 *sp)
829 {
830         u1          *ra;
831         u4           mcode;
832         methodinfo  *m;
833         s4           disp;
834         u1          *pv;
835         functionptr  f;
836
837         /* get stuff from the stack */
838
839         ra    = (u1 *)         *((ptrint *) (sp + 5 * 8));
840         mcode =                *((u4 *)     (sp + 3 * 8));
841         m     = (methodinfo *) *((ptrint *) (sp + 2 * 8));
842         disp  =                *((s4 *)     (sp + 1 * 8));
843         pv    = (u1 *)         *((ptrint *) (sp + 0 * 8));
844
845         /* calculate and set the new return address */
846
847         ra = ra - 1 * 4;
848         *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
849
850         /* resolve native function */
851
852         if (!(f = native_resolve_function(m)))
853                 return false;
854
855         /* patch back original code */
856
857         *((u4 *) ra) = mcode;
858
859         /* synchronize instruction cache */
860
861         md_icacheflush(NULL, 0);
862
863         /* patch native function pointer */
864
865         *((ptrint *) (pv + disp)) = (ptrint) f;
866
867         return true;
868 }
869 #endif /* !defined(WITH_STATIC_CLASSPATH) */
870
871
872 /*
873  * These are local overrides for various environment variables in Emacs.
874  * Please do not remove this and leave it at the end of the file, where
875  * Emacs will automagically detect them.
876  * ---------------------------------------------------------------------
877  * Local variables:
878  * mode: c
879  * indent-tabs-mode: t
880  * c-basic-offset: 4
881  * tab-width: 4
882  * End:
883  * vim:noexpandtab:sw=4:ts=4:
884  */