├── .classpath
├── .cproject
├── .gitignore
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── AUTHORS
├── Makefile
├── README
├── build.xml
├── config.mak.example
├── include
└── liboo
│ ├── ddispatch.h
│ ├── debuginfo.h
│ ├── dmemory.h
│ ├── eh.h
│ ├── oo.h
│ ├── opt.h
│ ├── rta.h
│ ├── rts_types.h
│ └── rtti.h
├── spec
├── config.example
├── generate_headerbindings.sh
├── javagen.sh
├── javaspec.py
└── oo_nodes_spec.py
├── src-cpp
├── adt
│ ├── align.h
│ ├── array.h
│ ├── bitfiddle.h
│ ├── compiler.h
│ ├── cpmap.c
│ ├── cpmap.h
│ ├── cpset.c
│ ├── cpset.h
│ ├── error.h
│ ├── fourcc.h
│ ├── hashptr.h
│ ├── hashset.c.h
│ ├── hashset.h
│ ├── obst.h
│ ├── obstack.c
│ ├── obstack.h
│ ├── obstack_printf.c
│ ├── pdeq.c
│ ├── pdeq.h
│ ├── pdeq.o
│ ├── raw_bitset.h
│ ├── util.h
│ └── xmalloc.h
├── ddispatch.c
├── debuginfo.c
├── dmemory.c
├── eh.c
├── nodes_attr.h
├── oo.c
├── opt.c
├── rt
│ ├── error_functions.c
│ ├── exceptions.c
│ ├── instanceof.c
│ ├── interface_lookup.c
│ ├── rt.h
│ └── types.h
├── rta.c
└── rtti.c
└── src
└── firm
├── DebugInfo.java
├── OO.java
├── RTA.java
├── bindings
├── binding_nodes.java
├── binding_oo.java
└── binding_rta.java
└── oo
└── nodes
├── Arraylength.java
├── InstanceOf.java
├── MethodSel.java
├── Nodes.java
└── VptrIsSet.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /classes
3 | /lib
4 | /config.mak
5 | /spec/config
6 | /include/liboo/nodes.h
7 | /src-cpp/gen_irnode.c
8 | /src-cpp/gen_irnode.h
9 | *.pyc
10 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | liboo
4 |
5 |
6 | jFirm
7 | libfirm
8 |
9 |
10 |
11 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
12 | clean,full,incremental,
13 |
14 |
15 | ?name?
16 |
17 |
18 |
19 | org.eclipse.cdt.make.core.append_environment
20 | true
21 |
22 |
23 | org.eclipse.cdt.make.core.autoBuildTarget
24 | all
25 |
26 |
27 | org.eclipse.cdt.make.core.buildArguments
28 |
29 |
30 |
31 | org.eclipse.cdt.make.core.buildCommand
32 | make
33 |
34 |
35 | org.eclipse.cdt.make.core.cleanBuildTarget
36 | clean
37 |
38 |
39 | org.eclipse.cdt.make.core.contents
40 | org.eclipse.cdt.make.core.activeConfigSettings
41 |
42 |
43 | org.eclipse.cdt.make.core.enableAutoBuild
44 | false
45 |
46 |
47 | org.eclipse.cdt.make.core.enableCleanBuild
48 | true
49 |
50 |
51 | org.eclipse.cdt.make.core.enableFullBuild
52 | true
53 |
54 |
55 | org.eclipse.cdt.make.core.fullBuildTarget
56 | all
57 |
58 |
59 | org.eclipse.cdt.make.core.stopOnError
60 | true
61 |
62 |
63 | org.eclipse.cdt.make.core.useDefaultBuildCmd
64 | true
65 |
66 |
67 |
68 |
69 | org.eclipse.jdt.core.javabuilder
70 |
71 |
72 |
73 |
74 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
75 | full,incremental,
76 |
77 |
78 |
79 |
80 |
81 | org.eclipse.jdt.core.javanature
82 | org.eclipse.cdt.core.cnature
83 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
84 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
85 |
86 |
87 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Fri Dec 03 12:47:22 CET 2010
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
4 | org.eclipse.jdt.core.compiler.problem.autoboxing=warning
5 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
6 | org.eclipse.jdt.core.compiler.problem.deadCode=warning
7 | org.eclipse.jdt.core.compiler.problem.deprecation=warning
8 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
9 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
10 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
11 | org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
12 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
13 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
14 | org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
15 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
16 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
17 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
18 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
19 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
20 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
21 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
22 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
23 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
24 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
25 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
26 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
27 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
28 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
29 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
30 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
31 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
32 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
33 | org.eclipse.jdt.core.compiler.problem.nullReference=error
34 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
35 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
36 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
37 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
38 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=error
39 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
40 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
41 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
42 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
43 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
44 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
45 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
46 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
47 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
48 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
49 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
50 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
51 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
52 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
53 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
54 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
55 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
56 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
57 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning
58 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
59 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
60 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
61 | org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
62 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
63 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
64 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
65 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
66 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
67 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
68 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Julian Oppermann
2 | Matthias Braun
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | variant ?= debug
2 |
3 | -include config.mak
4 |
5 | FIRM_HOME ?= ../libfirm
6 | LIBFIRM_CPPFLAGS ?= -I$(FIRM_HOME)/include -I$(FIRM_HOME)/build/gen/include/libfirm
7 | LIBFIRM_LFLAGS ?= -L$(FIRM_HOME)/build/$(variant) -lfirm
8 | INSTALL ?= install
9 | DLLEXT ?= .so
10 | CC ?= gcc
11 | AR ?= ar
12 | CFLAGS ?= -O0 -g3
13 |
14 | guessed_target := $(shell $(CC) -dumpmachine)
15 | TARGET ?= $(guessed_target)
16 | TARGET_CC ?= $(TARGET)-gcc
17 |
18 | ifeq ($(findstring darwin11, $(TARGET)), darwin11)
19 | # compile library normally but runtime in 32bit mode
20 | RT_CFLAGS += -m32
21 | RT_LFLAGS += -m32
22 | endif
23 | ifeq ($(findstring x86_64, $(guessed_target)), x86_64)
24 | ifeq ($(findstring i686, $(TARGET)), i686)
25 | # compile library normally but runtime in 32bit mode
26 | RT_CFLAGS += -m32
27 | RT_LFLAGS += -m32
28 | endif
29 | endif
30 | ifeq ($(findstring i686-invasic, $(TARGET)), i686-invasic)
31 | OCTOPOS_BASE=../octopos-app/releases/current/x86guest/default
32 | GCC_INCLUDE:=$(shell $(TARGET_CC) --print-file-name=include)
33 | RT_CFLAGS += -m32 -fno-stack-protector -mfpmath=sse -msse2 -nostdinc -isystem $(GCC_INCLUDE) -I $(OCTOPOS_BASE)/include -ffreestanding
34 | RT_LFLAGS += -m32 -nostdlib -Wl,-T,$(OCTOPOS_BASE)/lib/sections.x $(OCTOPOS_BASE)/lib/libcsubset.a $(OCTOPOS_BASE)/lib/liboctopos.a
35 | endif
36 | ifeq ($(findstring x86_64-invasic, $(TARGET)), x86_64-invasic)
37 | OCTOPOS_BASE=../octopos-app/releases/current/x64native/default
38 | GCC_INCLUDE:=$(shell $(TARGET_CC) --print-file-name=include)
39 | RT_CFLAGS += -mno-red-zone -nostdinc -isystem $(GCC_INCLUDE) -I $(OCTOPOS_BASE)/include -ffreestanding
40 | RT_LFLAGS += -nostdlib -Wl,-T,$(OCTOPOS_BASE)/lib/sections.x $(OCTOPOS_BASE)/lib/libcsubset.a $(OCTOPOS_BASE)/lib/liboctopos.a
41 | endif
42 | ifeq ($(findstring sparc-invasic, $(TARGET)), sparc-invasic)
43 | OCTOPOS_BASE=../octopos-app/releases/current/leon/default
44 | GCC_INCLUDE:=$(shell $(TARGET_CC) --print-file-name=include)
45 | RT_CFLAGS += -fno-stack-protector -nostdinc -I $(OCTOPOS_BASE)/include -isystem $(GCC_INCLUDE) -ffreestanding
46 | RT_LFLAGS += -nostdlib -Wl,-T,$(OCTOPOS_BASE)/lib/sections.x $(OCTOPOS_BASE)/lib/libcsubset.a $(OCTOPOS_BASE)/lib/liboctopos.a
47 | endif
48 |
49 | BUILDDIR=build
50 | RUNTIME_BUILDDIR=$(BUILDDIR)/$(TARGET)
51 | GOAL = $(BUILDDIR)/liboo$(DLLEXT)
52 | GOAL_STATIC = $(BUILDDIR)/liboo.a
53 | GOAL_RT_SHARED = $(RUNTIME_BUILDDIR)/liboo_rt$(DLLEXT)
54 | GOAL_RT_STATIC = $(RUNTIME_BUILDDIR)/liboo_rt.a
55 | # We only need a static runtime lib for invasic targets
56 | ifeq ($(findstring invasic, $(TARGET)), invasic)
57 | GOAL_RT_SHARED =
58 | endif
59 | CPPFLAGS = -I. -I./include/ $(LIBFIRM_CPPFLAGS) $(LIBUNWIND_CPPFLAGS)
60 | CFLAGS += -Wall -W -Wstrict-prototypes -Wmissing-prototypes -std=c99 -pedantic
61 | # disabled the following warnings for now. They fail on OS/X Snow Leopard:
62 | # the first one gives false positives because of system headers, the later one
63 | # doesn't exist in the old gcc there
64 | #CFLAGS += -Wunreachable-code -Wlogical-op
65 | LFLAGS +=
66 | PIC_FLAGS = -fpic
67 | SOURCES = $(wildcard src-cpp/*.c) $(wildcard src-cpp/adt/*.c)
68 | SOURCES_RT = $(wildcard src-cpp/rt/*.c)
69 | SOURCES := $(filter-out src-cpp/gen_%.c, $(SOURCES)) src-cpp/gen_irnode.c
70 | OBJECTS = $(addprefix $(BUILDDIR)/, $(addsuffix .o, $(basename $(SOURCES))))
71 | OBJECTS_RT_SHARED = $(addprefix $(RUNTIME_BUILDDIR)/shared/, $(addsuffix .o, $(basename $(SOURCES_RT))))
72 | OBJECTS_RT_STATIC = $(addprefix $(RUNTIME_BUILDDIR)/static/, $(addsuffix .o, $(basename $(SOURCES_RT))))
73 | DEPS = $(OBJECTS:%.o=%.d) $(OBJECTS_RT_SHARED:%.o=%.d) $(OBJECTS_RT_STATIC:%.o=%.d)
74 |
75 | Q ?= @
76 |
77 | .PHONY: all runtime clean
78 |
79 | all: $(GOAL) $(GOAL_STATIC) runtime
80 |
81 | runtime: $(GOAL_RT_SHARED) $(GOAL_RT_STATIC)
82 |
83 | # Make sure our build-directories are created
84 | UNUSED := $(shell mkdir -p $(BUILDDIR)/src-cpp/rt $(BUILDDIR)/src-cpp/adt $(RUNTIME_BUILDDIR)/shared/src-cpp/rt $(RUNTIME_BUILDDIR)/static/src-cpp/rt)
85 |
86 | -include $(DEPS)
87 |
88 | SPEC_GENERATED_HEADERS := include/liboo/nodes.h src-cpp/gen_irnode.h
89 | SPECGENDIR := $(FIRM_HOME)/scripts
90 | IR_SPEC_GENERATOR := $(SPECGENDIR)/gen_ir.py
91 | IR_SPEC_GENERATOR_DEPS := $(IR_SPEC_GENERATOR) $(SPECGENDIR)/irops.py $(SPECGENDIR)/filters.py $(SPECGENDIR)/jinjautil.py
92 | SPECFILE := spec/oo_nodes_spec.py
93 |
94 | $(SOURCES): $(SPEC_GENERATED_HEADERS)
95 |
96 | include/liboo/% : $(FIRM_HOME)/scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(SPECFILE)
97 | @echo GEN $@
98 | $(Q)$(IR_SPEC_GENERATOR) "$(SPECFILE)" "$<" > "$@"
99 |
100 | src-cpp/% : $(FIRM_HOME)/scripts/templates/% $(IR_SPEC_GENERATOR_DEPS) $(SPECFILE)
101 | @echo GEN $@
102 | $(Q)$(IR_SPEC_GENERATOR) "$(SPECFILE)" "$<" > "$@"
103 |
104 | $(GOAL): $(OBJECTS)
105 | @echo '===> LD $@'
106 | $(Q)$(CC) -shared -o $@ $^ $(LFLAGS) $(LIBFIRM_LFLAGS)
107 |
108 | $(GOAL_STATIC): $(OBJECTS)
109 | @echo '===> AR $@'
110 | $(Q)$(AR) -cr $@ $^
111 |
112 | $(GOAL_RT_SHARED): $(OBJECTS_RT_SHARED)
113 | @echo '===> LD $@'
114 | $(Q)$(TARGET_CC) -shared $(RT_LFLAGS) $(PIC_FLAGS) -o $@ $^ $(LFLAGS) $(LIBUNWIND_LFLAGS)
115 |
116 | $(GOAL_RT_STATIC): $(OBJECTS_RT_STATIC)
117 | @echo '===> AR $@'
118 | $(Q)$(AR) -cr $@ $^
119 |
120 | $(RUNTIME_BUILDDIR)/shared/%.o: %.c
121 | @echo '===> TARGET_CC $@'
122 | $(Q)$(TARGET_CC) $(CPPFLAGS) $(CFLAGS) $(RT_CFLAGS) $(PIC_FLAGS) -MP -MMD -c -o $@ $<
123 |
124 | $(RUNTIME_BUILDDIR)/static/%.o: %.c
125 | @echo '===> TARGET_CC $@'
126 | $(Q)$(TARGET_CC) $(CPPFLAGS) $(CFLAGS) $(RT_CFLAGS) -MP -MMD -c -o $@ $<
127 |
128 | $(BUILDDIR)/%.o: %.c
129 | @echo '===> CC $@'
130 | $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(PIC_FLAGS) -MP -MMD -c -o $@ $<
131 |
132 | clean:
133 | rm -rf $(OBJECTS) $(OBJECTS_RT_SHARED) $(OBJECTS_RT_STATIC) $(GOAL) $(GOAL_RT_STATIC) $(GOAL_RT_SHARED) $(DEPS) $(DEPS_RT) $(RUNTIME_BUILDDIR) $(SPEC_GENERATED_HEADERS)
134 |
135 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This library provides support for compilation of object-oriented constructs in firm. Since firm mostly deals with low-level things you need an additional layer to produce things like vtable or name-mangling. This library provides them.
2 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 | firm object-orientation support library
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | FIRM_HOME = ../libfirm
35 | LIBFIRM_CPPFLAGS = -I$(FIRM_HOME)/include -I$(FIRM_HOME)/build/gen/include/libfirm
36 | LIBFIRM_LFLAGS = -L$(FIRM_HOME)/build/$(variant) -lfirm
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/config.mak.example:
--------------------------------------------------------------------------------
1 | FIRM_HOME = ../libfirm
2 | LIBFIRM_CPPFLAGS = -I$(FIRM_HOME)/include -I$(FIRM_HOME)/build/gen/include/libfirm
3 | LIBFIRM_LFLAGS = -L$(FIRM_HOME)/build/debug -lfirm
4 |
--------------------------------------------------------------------------------
/include/liboo/ddispatch.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_DDISPATCH_H
2 | #define OO_DDISPATCH_H
3 |
4 | /*
5 | * Layout of the created dynamic dispatch table (vtable):
6 | *
7 | * Default layout:
8 | *
9 | * _ZTVNxyzE:
10 | * runtime classinfo
11 | * addr(first method)
12 | * ...
13 | * addr(last method)
14 | *
15 | * More complicated layouts are possible, use ddispatch_set_vtable_layout(..).
16 | * The resulting vtable will look like this:
17 | *
18 | * _ZTVNxyzE:
19 | * 0 uninitialized*
20 | * 0 uninitialized*
21 | * runtime classinfo <-- vtable_vptr_points_to_index (e.g., == 2)
22 | * uninitialized*
23 | * addr(first method) <-- vtable_index_of_first_method (e.g., == 4)
24 | * ...
25 | * addr(last method)
26 | *
27 | * *) use callback function vtable_init_slots to set ir_initializer_t's
28 | * for the uninitialized slots.
29 | */
30 |
31 | #include
32 |
33 | /*
34 | * This property specifies how a
35 | *
36 | * class method entity
37 | * \ /
38 | * Sel
39 | * |
40 | * Call
41 | *
42 | * construction should be lowered.
43 | *
44 | * bind_static : no further indirection should be performed, just call the specified method.
45 | * bind_dynamic : use the vtable mechanism to determine the real callee.
46 | * bind_interface: invoke a special lookup method at runtime to get the callee.
47 | *
48 | * NOTE: This does not distinguish class/static vs. instance methods or fields.
49 | *
50 | */
51 | typedef enum {
52 | bind_unknown,
53 | bind_static,
54 | bind_dynamic,
55 | bind_interface
56 | } ddispatch_binding;
57 |
58 | typedef enum {
59 | call_runtime_lookup = 0,
60 | call_searched_itable = 1,
61 | call_itable_indexed = 2,
62 | call_move2front = 4
63 | } ddispatch_interface_call;
64 |
65 |
66 | typedef void (*init_vtable_slots_t) (ir_type* klass, ir_initializer_t *vtable_init, unsigned vtable_size);
67 | typedef ir_node* (*construct_interface_lookup_t) (ir_node *objptr, ir_type *iface, ir_entity *method, ir_graph *irg, ir_node *block, ir_node **mem);
68 |
69 | void ddispatch_init(void);
70 | void ddispatch_deinit(void);
71 | void ddispatch_setup_vtable(ir_type *klass);
72 | void ddispatch_lower_Call(ir_node* call);
73 | void ddispatch_prepare_new_instance(dbg_info *dbgi, ir_node *block, ir_node *objptr, ir_node **mem, ir_type* klass);
74 |
75 | void ddispatch_setup_itable(ir_type *klass);
76 | int ddispatch_get_itable_method_index(ir_type *interface, ir_entity *method);
77 | ir_entity *ddispatch_get_itable_id(ir_type *interface);
78 | unsigned ddispatch_get_itable_index(ir_type *interface);
79 | ir_type *ddispatch_get_itt_entry_type(void);
80 |
81 |
82 | void ddispatch_set_vtable_layout(unsigned vptr_points_to_index, unsigned index_of_first_method, unsigned index_of_rtti_ptr, init_vtable_slots_t func);
83 | void ddispatch_set_interface_lookup_constructor(construct_interface_lookup_t func);
84 | void ddispatch_set_abstract_method_entity(ir_entity *method);
85 |
86 | unsigned ddispatch_get_vptr_points_to_index(void);
87 | unsigned ddispatch_get_index_of_rtti_ptr(void);
88 | unsigned ddispatch_get_index_of_first_method(void);
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/include/liboo/debuginfo.h:
--------------------------------------------------------------------------------
1 | #ifndef DEBUGINFO_H
2 | #define DEBUGINFO_H
3 |
4 | #include
5 |
6 | void debuginfo_init(void);
7 | const dbg_info *create_debuginfo(ident *filename, unsigned linenr,
8 | unsigned column, unsigned length);
9 | void debuginfo_deinit(void);
10 |
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/include/liboo/dmemory.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_DMEMORY_H
2 | #define OO_DMEMORY_H
3 |
4 | #include
5 |
6 | typedef ir_node* (*get_arraylength_t) (dbg_info *dbgi, ir_node *block, ir_node *objptr, ir_node **mem);
7 |
8 | ir_node *dmemory_default_get_arraylength(dbg_info *dbgi, ir_node *block, ir_node *objptr, ir_node **mem);
9 |
10 | void dmemory_init(void);
11 | void dmemory_lower_Arraylength(ir_node* arraylength);
12 | void dmemory_set_allocation_methods(get_arraylength_t ga_func);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/include/liboo/eh.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_EH_H
2 | #define OO_EH_H
3 |
4 | #include
5 |
6 | void eh_init(void);
7 | void eh_deinit(void);
8 |
9 | void eh_start_method(void);
10 | void eh_new_lpad(void);
11 | void eh_add_handler(ir_type *catch_type, ir_node *block);
12 | void eh_pop_lpad(void);
13 | void eh_end_method(void);
14 |
15 | ir_node *eh_get_exception_object(void);
16 | ir_node *eh_new_Call(ir_node * irn_ptr, int arity, ir_node *const * in, ir_type* catch_type);
17 | void eh_throw(ir_node *exo_ptr);
18 |
19 | void eh_lower_Raise(ir_node *raise, ir_node *proj);
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/include/liboo/oo.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_OO_H
2 | #define OO_OO_H
3 |
4 | #include
5 | #include
6 |
7 | #include "ddispatch.h"
8 | #include "rta.h"
9 |
10 | void oo_init(void);
11 | void oo_deinit(void);
12 | void oo_lower(void);
13 |
14 | void oo_set_interface_call_type(ddispatch_interface_call type);
15 | ddispatch_interface_call oo_get_interface_call_type(void);
16 |
17 |
18 | unsigned oo_get_class_uid(ir_type *classtype);
19 | void oo_set_class_uid(ir_type *classtype, unsigned uid);
20 | ir_entity *oo_get_class_vtable_entity(ir_type *classtype);
21 | void oo_set_class_vtable_entity(ir_type *classtype, ir_entity *vtable);
22 | unsigned oo_get_class_vtable_size(ir_type *classtype);
23 | void oo_set_class_vtable_size(ir_type *classtype, unsigned vtable_size);
24 | ir_entity *oo_get_class_vptr_entity(ir_type *classtype);
25 | void oo_set_class_vptr_entity(ir_type *classtype, ir_entity *vptr);
26 | ir_entity *oo_get_class_rtti_entity(ir_type *classtype);
27 | void oo_set_class_rtti_entity(ir_type *classtype, ir_entity *rtti);
28 | ir_entity *oo_get_class_itt_entity(ir_type *classtype);
29 | void oo_set_class_itt_entity(ir_type *classtype, ir_entity *itt);
30 | bool oo_get_class_is_interface(ir_type *classtype);
31 | void oo_set_class_is_interface(ir_type *classtype, bool is_interface);
32 | bool oo_get_class_is_abstract(ir_type *classtype);
33 | void oo_set_class_is_abstract(ir_type *classtype, bool is_abstract);
34 | bool oo_get_class_is_final(ir_type *classtype);
35 | void oo_set_class_is_final(ir_type *classtype, bool is_final);
36 | bool oo_get_class_is_extern(ir_type *classtype);
37 | void oo_set_class_is_extern(ir_type *classtype, bool is_extern);
38 |
39 | void *oo_get_type_link(ir_type *type);
40 | void oo_set_type_link(ir_type *type, void* link);
41 |
42 | bool oo_get_method_exclude_from_vtable(ir_entity *method);
43 | void oo_set_method_exclude_from_vtable(ir_entity *method, bool exclude_from_vtable);
44 | int oo_get_method_vtable_index(ir_entity *method);
45 | void oo_set_method_vtable_index(ir_entity *method, int vtable_slot);
46 | bool oo_get_method_is_abstract(ir_entity *method);
47 | void oo_set_method_is_abstract(ir_entity *method, bool is_abstract);
48 | bool oo_get_method_is_final(ir_entity *method);
49 | void oo_set_method_is_final(ir_entity *method, bool is_final);
50 | bool oo_get_method_is_inherited(ir_entity *method);
51 | void oo_set_method_is_inherited(ir_entity *method, bool is_inherited);
52 |
53 | bool oo_get_field_is_transient(ir_entity *field);
54 | void oo_set_field_is_transient(ir_entity *field, bool is_transient);
55 |
56 | ddispatch_binding oo_get_entity_binding(ir_entity *entity);
57 | void oo_set_entity_binding(ir_entity *entity, ddispatch_binding binding);
58 | void *oo_get_entity_link(ir_entity *entity);
59 | void oo_set_entity_link(ir_entity *entity, void* link);
60 |
61 | void oo_set_call_is_statically_bound(ir_node *call, bool bind_statically);
62 | bool oo_get_call_is_statically_bound(ir_node *call);
63 |
64 | ir_type *oo_get_class_superclass(ir_type *klass);
65 | ir_entity *oo_get_entity_overwritten_superclass_entity(ir_entity *entity);
66 |
67 | void oo_copy_entity_info(ir_entity *src, ir_entity *dest);
68 |
69 | #endif
70 |
--------------------------------------------------------------------------------
/include/liboo/opt.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_OPT_H
2 | #define OO_OPT_H
3 |
4 | /**
5 | * register transform_Node/equivalent_node/computed_value optimization
6 | * callbacks for liboo specific nodes.
7 | */
8 | void oo_register_opt_funcs(void);
9 |
10 | #endif
11 |
--------------------------------------------------------------------------------
/include/liboo/rta.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of liboo.
3 | */
4 |
5 | /**
6 | * @file rta.h
7 | * @brief Devirtualization of dynamically bound calls through Rapid Type Analysis
8 | * @author Steffen Knoth
9 | * @date 2014
10 | */
11 |
12 |
13 | #ifndef OO_RTA_H
14 | #define OO_RTA_H
15 |
16 |
17 | #include
18 |
19 | /** sets important callback functions needed to detect calls (e.g. class intialization) hidden behind frontend-specific nodes
20 | * @note It's very important for the frontend to implement these callbacks correctly, if anything is missing RTA's assumptions may not hold and it can lead to defective programs!
21 | * @note This mechanism is meant for functions similar to e.g. _Jv_InitClass that hide calls to analyzable methods in native code.
22 | * @note It doesn't make much sense to return entities of native functions or methods. Return methods that can and should be analyzed even if they are called indirectly by other native methods that are called by the method/function in question.
23 | * @note The callbacks are only called on statically bound call nodes that call a function that has no firm graph.
24 | * @param detect_call give function that returns the entity (ir_entity*) of the method called by the call node or NULL if no method is called //TODO support for more than one
25 | */
26 | void rta_set_detection_callbacks(ir_entity *(*detect_call)(ir_node *call));
27 |
28 |
29 | /** runs Rapid Type Analysis and then tries to devirtualize dynamically bound calls and to discard unneeded classes and methods
30 | * @note RTA requires object creations to be marked with VptrIsSet nodes.
31 | * @note RTA requires the analyzed code to be typesafe, meaning objects on which dynamically bound calls are invoked have to be of the static type of the reference or a subclass of it, otherwise the results can be incorrect and can lead to defective programs!
32 | * @note RTA must know of _all_ definitely executed code parts (main, class initializers, global contructors or all nonprivate functions if it's a library)! It's important to give absolutely _all_ entry points because RTA builds on a closed world assumption. Otherwise the results can be incorrect and can lead to defective programs!
33 | * @note RTA also won't work with programs that dynamically load classes at runtime or use generic object creation (like Java Class.newInstance)! It can lead to defective programs!
34 | * @note Give classes that are instantiated in native methods of a nonexternal standard library or runtime as initial_live_classes, give methods called in these native methods as additional entry points. If something is missing, RTA could produce defective programs! This also means that native methods in the program that do arbitrary things are not supported as long as there is no way to tell RTA what classes are instantiated and what methods are called in all those native methods.
35 | * @note C++ is currently not supported (C++ constructor semantics, function pointers, ...).
36 | * @param entry_points NULL-terminated array of method entities, give all entry points to program code, may _not_ be NULL and must contain at least one method entity, also all entry points should have a graph
37 | * @param initial_live_classes NULL-terminated array of classes that should always be considered live, may be NULL
38 | */
39 | void rta_optimization(ir_entity** entry_points, ir_type **initial_live_classes);
40 |
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/include/liboo/rts_types.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * Structure of runtime type information as emitted by liboo.
4 | *
5 | * Warning: if you change this struct, also change the code in rtti.c which
6 | * emits this data during a compilation run
7 | */
8 | #ifndef OO_RTS_TYPES_H
9 | #define OO_RTS_TYPES_H
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | typedef struct {
16 | uint32_t hash;
17 | char data[];
18 | } string_const_t;
19 |
20 | typedef struct {
21 | string_const_t *name; /* including signature */
22 | void *funcptr;
23 | } method_info_t;
24 |
25 | struct class_info_t {
26 | string_const_t *name;
27 | uint32_t uid;
28 | size_t size;
29 | struct class_info_t *superclass;
30 | uint32_t n_methods;
31 | method_info_t *methods;
32 | uint32_t n_interfaces;
33 | struct class_info_t **interfaces;
34 | };
35 | typedef struct class_info_t class_info_t;
36 |
37 | typedef struct {
38 | void *ip;
39 | void *handler;
40 | } lsda_entry_t;
41 |
42 | typedef struct {
43 | uint32_t n_entries;
44 | lsda_entry_t entries[1];
45 | } lsda_t;
46 |
47 | inline static const char *get_string_const_chars(const string_const_t *s)
48 | {
49 | return s->data;
50 | }
51 |
52 | inline static uint32_t string_hash(const char* s)
53 | {
54 | uint32_t hash = 0;
55 | for (const char *c = s; *c != '\0'; ++c) {
56 | hash = (31 * hash) ^ *c;
57 | }
58 | return hash;
59 | }
60 |
61 | inline static bool string_const_equals(const string_const_t *s1,
62 | const string_const_t *s2)
63 | {
64 | /* cannot be equal if hashes don't match */
65 | if (s1->hash != s2->hash)
66 | return false;
67 | if (s1 == s2)
68 | return true;
69 |
70 | char *p1 = (char*)&s1->data;
71 | char *p2 = (char*)&s2->data;
72 | while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2) {
73 | p1++; p2++;
74 | }
75 | /* true if both strings reached the end (and thus must be equal) */
76 | return (*p1 == '\0' && *p2 == '\0');
77 |
78 | }
79 | #endif
80 |
--------------------------------------------------------------------------------
/include/liboo/rtti.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_RTTI_H
2 | #define OO_RTTI_H
3 |
4 | #include
5 |
6 | typedef void (*construct_runtime_typeinfo_t) (ir_type *klass);
7 | typedef ir_node *(*construct_instanceof_t) (ir_node *objptr, ir_type *klass, ir_graph *irg, ir_node *block, ir_node **mem);
8 |
9 | void rtti_default_construct_runtime_typeinfo(ir_type *klass);
10 | ir_node *rtti_default_construct_instanceof(ir_node *objptr, ir_type *klass, ir_graph *irg, ir_node *block, ir_node **mem);
11 |
12 | void rtti_init(void);
13 | void rtti_deinit(void);
14 | void rtti_construct_runtime_typeinfo(ir_type *klass);
15 | void rtti_lower_InstanceOf(ir_node *instanceof);
16 | void rtti_set_runtime_typeinfo_constructor(construct_runtime_typeinfo_t func);
17 | void rtti_set_instanceof_constructor(construct_instanceof_t func);
18 |
19 | ir_entity *rtti_emit_string_const(const char *bytes);
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/spec/config.example:
--------------------------------------------------------------------------------
1 | FIRM_HOME="../../libfirm"
2 | FIRM_INC="${FIRM_HOME}/include"
3 | FIRM_INC2="${FIRM_HOME}/build/gen/include/libfirm"
4 | FIRM_BUILD="${FIRM_HOME}/build/debug/"
5 |
--------------------------------------------------------------------------------
/spec/generate_headerbindings.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # You need a new version cparser (with jna backend) and firm headers
4 | set -eu
5 |
6 | . ./config
7 |
8 | for i in oo nodes rta ; do
9 | RES="../src/firm/bindings/binding_$i.java"
10 | TMP="/tmp/tmp.java"
11 | TMP2="/tmp/tmp2.java"
12 | OO_INC="../include"
13 | echo " * Creating $RES"
14 | CMD="cparser --print-jna --jna-libname oo -I${FIRM_INC} -I${FIRM_INC2} -I${OO_INC} ${OO_INC}/liboo/$i.h --jna-limit ${OO_INC}/liboo/$i.h"
15 | echo "$CMD"
16 | $CMD > $TMP || exit $?
17 | sed -e "s/class binding/class binding_$i/g" -i $TMP
18 | echo "package firm.bindings;" > $TMP2
19 | echo "" >> $TMP2
20 | cat $TMP2 $TMP > $RES
21 | done
22 |
23 |
--------------------------------------------------------------------------------
/spec/javagen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -eu
4 |
5 | FIRM_HOME="../../libfirm"
6 | JFIRM_HOME="../../jFirm"
7 | GENERATOR="python ${FIRM_HOME}/scripts/gen_ir.py -I${JFIRM_HOME}/binding_generator -I. javaspec.py"
8 |
9 | #$GENERATOR templates/Node.java
10 | echo "Create: Nodes.java"
11 | $GENERATOR templates/Nodes.java > ../src/firm/oo/nodes/Nodes.java
12 |
13 | $GENERATOR templates/nodelist > /tmp/nodelist
14 | for n in $(cat /tmp/nodelist); do
15 | GOAL="../src/firm/oo/nodes/$n.java"
16 | echo "GEN $GOAL"
17 | $GENERATOR -DNODENAME=$n templates/Node.java > $GOAL
18 | done
19 |
--------------------------------------------------------------------------------
/spec/javaspec.py:
--------------------------------------------------------------------------------
1 | from oo_nodes_spec import nodes, abstract_nodes
2 | from javabits import preprocess_node
3 | from jinjautil import export
4 |
5 | java_binding = "firm.bindings.binding_nodes"
6 | java_package = "firm.oo.nodes"
7 | export(java_package, "java_package")
8 | export(java_binding, "java_binding")
9 |
10 | for node in nodes+abstract_nodes:
11 | preprocess_node(node)
12 |
--------------------------------------------------------------------------------
/spec/oo_nodes_spec.py:
--------------------------------------------------------------------------------
1 | from irops import op, Attribute, prepare_nodes, Node
2 | from jinjautil import export
3 |
4 | name = "oo"
5 | external = "liboo"
6 |
7 | @op
8 | class InstanceOf(Node):
9 | """Check if an object is an instance of a specified type (or a subtype).
10 | Passing a null pointer results in undefined behaviour."""
11 | ins = [
12 | ("mem", "memory dependency"),
13 | ("ptr", "pointer to object"),
14 | ]
15 | outs = [
16 | ("M", "memory result"),
17 | ("res", "result of instanceof check"), # mode_b
18 | ]
19 | attrs = [
20 | Attribute("type", type="ir_type*", comment="classtype to check for"),
21 | ]
22 | flags = [ "uses_memory" ]
23 | pinned = "no"
24 | attr_struct = "op_InstanceOf_attr_t"
25 |
26 | @op
27 | class Arraylength(Node):
28 | """Return the lenght of a (dynamic) array"""
29 | ins = [
30 | ("mem", "memory dependency"),
31 | ("ptr", "pointer to array"),
32 | ]
33 | outs = [
34 | ("M", "memory result"),
35 | ("res", "length of the array"),
36 | ]
37 | flags = [ "uses_memory" ]
38 | pinned = "no"
39 |
40 | @op
41 | class MethodSel(Node):
42 | """Performs a vtable lookup for a method (or rtti info)."""
43 | ins = [
44 | ("mem", "memory dependency"),
45 | ("ptr", "pointer to an object with a vtable"),
46 | ]
47 | outs = [
48 | ("M", "memory result"),
49 | ("res", "address of method"),
50 | ]
51 | attrs = [
52 | Attribute("entity", type="ir_entity*",
53 | comment="method entity which should be selected"),
54 | ]
55 | attr_struct = "op_MethodSel_attr_t"
56 | flags = [ "uses_memory" ]
57 | pinned = "no"
58 |
59 | @op
60 | class VptrIsSet(Node):
61 | """Mark that an objects vptr has been set. This node duplicates its pointer
62 | input and guarantees that all users of this node have an object of the
63 | specified type.
64 |
65 | In practice you would put such a node behind allocation calls in a java-like
66 | language or behind an external constructor call in a C++-like language.
67 |
68 | You could think of this as a special case of Confirm node, ensuring a
69 | certain object type."""
70 | ins = [
71 | ("mem", "memory dependency"),
72 | ("ptr", "pointer to an object"),
73 | ]
74 | outs = [
75 | ("M", "memory result"),
76 | ("res", "pointer to object"),
77 | ]
78 | attrs = [
79 | Attribute("type", type="ir_type*",
80 | comment="type of the object"),
81 | ]
82 | attr_struct = "op_VptrIsSet_attr_t"
83 | flags = [ "uses_memory" ]
84 | pinned = "no"
85 |
86 | (nodes, abstract_nodes) = prepare_nodes(globals())
87 | export(nodes, "nodes")
88 | export(abstract_nodes, "abstract_nodes")
89 | export(globals(), "spec")
90 |
--------------------------------------------------------------------------------
/src-cpp/adt/align.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief macros for alignment.
23 | * @author Markus Armbruster
24 | * @version $Id: align.h 17143 2008-01-02 20:56:33Z beck $
25 | */
26 | #ifndef FIRM_ADT_ALIGN_H
27 | #define FIRM_ADT_ALIGN_H
28 |
29 | #include
30 |
31 | /** A size handled efficiently by malloc(), at least 1K. */
32 | #define PREF_MALLOC_SIZE 2048
33 |
34 |
35 | /** A wrapper around GNU C's __attribute__ */
36 |
37 | /* According to the documentation, the attributes we are interested in
38 | work with 2.5, but we encountered trouble before 2.7. */
39 | #if defined (__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 7
40 | # define HAVE_ATTRIBUTE 1
41 | # define ATTRIBUTE(attrs) __attribute__ (attrs)
42 | #else
43 | # define ATTRIBUTE(attrs)
44 | #endif
45 |
46 |
47 | /* Alignment */
48 |
49 | /** A type that has most constrained alignment. */
50 | typedef union {
51 | long double d;
52 | void *p;
53 | long l;
54 | } aligned_type ATTRIBUTE ((aligned));
55 |
56 | /** Inquiring about the alignment of a type. */
57 | #ifdef __GNUC__
58 | # define ALIGNOF(type) __alignof__ (type)
59 | #else
60 | # define ALIGNOF(type) offsetof (struct { char c; type d; }, d)
61 | #endif
62 |
63 | /** Maximal alignment required for any type. */
64 | #define MAX_ALIGN ALIGNOF (aligned_type)
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/src-cpp/adt/array.h:
--------------------------------------------------------------------------------
1 | #include
2 |
--------------------------------------------------------------------------------
/src-cpp/adt/bitfiddle.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @date 28.9.2004
23 | * @brief Functions from hackers delight.
24 | * @author Sebastian Hack, Matthias Braun
25 | * @version $Id: bitfiddle.h 27155 2010-02-14 14:38:55Z mallon $
26 | */
27 | #ifndef FIRM_ADT_BITFIDDLE_H
28 | #define FIRM_ADT_BITFIDDLE_H
29 |
30 | #include "compiler.h"
31 |
32 | #include
33 | #include
34 |
35 | /* some functions here assume ints are 32 bit wide */
36 | #define HACKDEL_WORDSIZE 32
37 | COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
38 | COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
39 |
40 | /**
41 | * Add saturated.
42 | * @param x Summand 1.
43 | * @param y Summand 2.
44 | * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
45 | *
46 | * @note See hacker's delight, page 27.
47 | */
48 | static inline int add_saturated(int x, int y)
49 | {
50 | int sum = x + y;
51 | /*
52 | An overflow occurs, if the sign of the both summands is equal
53 | and the one of the sum is different from the summand's one.
54 | The sign bit is 1, if an overflow occurred, 0 otherwise.
55 | int overflow = ~(x ^ y) & (sum ^ x);
56 | */
57 | int overflow = (x ^ sum) & (y ^ sum);
58 |
59 | /*
60 | The infinity to use.
61 | Make a mask of the sign bit of x and y (they are the same if an
62 | overflow occurred).
63 | INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
64 | INT_MIN.
65 | */
66 | int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
67 |
68 | return overflow < 0 ? inf : sum;
69 | }
70 |
71 | /**
72 | * Compute the count of set bits in a 32-bit word.
73 | * @param x A 32-bit word.
74 | * @return The number of bits set in x.
75 | */
76 | static inline unsigned popcnt(unsigned x)
77 | {
78 | x -= ((x >> 1) & 0x55555555);
79 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
80 | x = (x + (x >> 4)) & 0x0f0f0f0f;
81 | x += x >> 8;
82 | x += x >> 16;
83 | return x & 0x3f;
84 | }
85 |
86 | /**
87 | * Compute the number of leading zeros in a word.
88 | * @param x The word.
89 | * @return The number of leading (from the most significant bit) zeros.
90 | */
91 | static inline unsigned nlz(unsigned x)
92 | {
93 | #ifdef USE_X86_ASSEMBLY
94 | unsigned res;
95 | if(x == 0)
96 | return 32;
97 |
98 | __asm__("bsrl %1,%0"
99 | : "=r" (res)
100 | : "r" (x));
101 | return 31 - res;
102 | #else
103 | unsigned y;
104 | int n = 32;
105 |
106 | y = x >>16; if (y != 0) { n -= 16; x = y; }
107 | y = x >> 8; if (y != 0) { n -= 8; x = y; }
108 | y = x >> 4; if (y != 0) { n -= 4; x = y; }
109 | y = x >> 2; if (y != 0) { n -= 2; x = y; }
110 | y = x >> 1; if (y != 0) return n - 2;
111 | return n - x;
112 | #endif
113 | }
114 |
115 | /**
116 | * Compute the number of trailing zeros in a word.
117 | * @param x The word.
118 | * @return The number of trailing zeros.
119 | */
120 | static inline unsigned ntz(unsigned x)
121 | {
122 | #ifdef USE_X86_ASSEMBLY
123 | unsigned res;
124 | if(x == 0)
125 | return 32;
126 |
127 | __asm__("bsfl %1,%0"
128 | : "=r" (res)
129 | : "r" (x));
130 | return res;
131 | #else
132 | return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
133 | #endif
134 | }
135 |
136 | /**
137 | * Compute the greatest power of 2 smaller or equal to a value.
138 | * This is also known as the binary logarithm.
139 | * @param x The value.
140 | * @return The power of two.
141 | */
142 | #define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
143 |
144 | /**
145 | * Compute the smallest power of 2 greater or equal to a value.
146 | * This is also known as the binary logarithm.
147 | * @param x The value.
148 | * @return The power of two.
149 | */
150 | #define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
151 |
152 | /**
153 | * Round up to the next multiple of a power of two.
154 | * @param x A value.
155 | * @param pot A power of two.
156 | * @return x rounded up to the next multiple of pot.
157 | */
158 | #define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
159 |
160 | /**
161 | * Returns the biggest power of 2 that is equal or smaller than @p x
162 | * (see hackers delight power-of-2 boundaries, page 48)
163 | */
164 | static inline unsigned floor_po2(unsigned x)
165 | {
166 | #ifdef USE_X86_ASSEMBLY // in this case nlz is fast
167 | if(x == 0)
168 | return 0;
169 | // note that x != 0 here, so nlz(x) < 32!
170 | return 0x80000000U >> nlz(x);
171 | #else
172 | x |= x >> 1;
173 | x |= x >> 2;
174 | x |= x >> 4;
175 | x |= x >> 8;
176 | x |= x >> 16;
177 | return x - (x >> 1);
178 | #endif
179 | }
180 |
181 | /**
182 | * Returns the smallest power of 2 that is equal or greater than x
183 | * @remark x has to be <= 0x8000000 of course
184 | * @note see hackers delight power-of-2 boundaries, page 48
185 | */
186 | static inline unsigned ceil_po2(unsigned x)
187 | {
188 | if(x == 0)
189 | return 0;
190 | assert(x < (1U << 31));
191 |
192 | #ifdef USE_X86_ASSEMBLY // in this case nlz is fast
193 | // note that x != 0 here!
194 | return 0x80000000U >> (nlz(x-1) - 1);
195 | #else
196 | x = x - 1;
197 | x |= x >> 1;
198 | x |= x >> 2;
199 | x |= x >> 4;
200 | x |= x >> 8;
201 | x |= x >> 16;
202 | return x + 1;
203 | #endif
204 | }
205 |
206 | /**
207 | * Tests whether @p x is a power of 2
208 | */
209 | static inline int is_po2(unsigned x)
210 | {
211 | return (x & (x-1)) == 0;
212 | }
213 |
214 | #endif
215 |
--------------------------------------------------------------------------------
/src-cpp/adt/compiler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @date 04.06.2007
23 | * @author Matthias Braun, Sebastian Hack
24 | * @brief Macros to instruct the compiler compiling libFirm.
25 | */
26 |
27 | #ifndef FIRM_COMPILER_H
28 | #define FIRM_COMPILER_H
29 |
30 | /**
31 | * Asserts that the constant expression x is not zero at compiletime. name has
32 | * to be a unique identifier.
33 | *
34 | * @note This uses the fact, that double case labels are not allowed.
35 | */
36 | #define COMPILETIME_ASSERT(x, name) \
37 | static __attribute__((unused)) void compiletime_assert_##name (int h) { \
38 | switch(h) { case 0: case (x): ; } \
39 | }
40 |
41 | #ifdef __GNUC__
42 | /**
43 | * Indicates to the compiler that the value of x is very likely 1
44 | * @note Only use this in speed critical code and when you are sure x is often 1
45 | */
46 | #define LIKELY(x) __builtin_expect((x), 1)
47 |
48 | /**
49 | * Indicates to the compiler that it's very likely that x is 0
50 | * @note Only use this in speed critical code and when you are sure x is often 0
51 | */
52 | #define UNLIKELY(x) __builtin_expect((x), 0)
53 |
54 | /**
55 | * Tell the compiler, that a function is pure, i.e. it only
56 | * uses its parameters and never modifies the "state".
57 | * Add this macro after the return type.
58 | */
59 | #define PURE __attribute__((const))
60 |
61 | #else
62 | #define LIKELY(x) x
63 | #define UNLIKELY(x) x
64 | #define PURE
65 | #endif
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/src-cpp/adt/cpmap.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief Custom pointer set
23 | * @author Matthias Braun
24 | * @version $Id: cpmap.c 17143 2008-01-02 20:56:33Z beck $
25 | *
26 | * This implements a set of pointers which allows to specify custom callbacks
27 | * for comparing and hashing it's elements.
28 | */
29 | #include "cpmap.h"
30 |
31 | #define HashSet cpmap_t
32 | #define HashSetIterator cpmap_iterator_t
33 | #define HashSetEntry cpmap_hashset_entry_t
34 | #define ValueType cpmap_entry_t
35 | #define NullValue (cpmap_entry_t) { NULL, NULL }
36 | #define DeletedValue (cpmap_entry_t) { ((void*)-1), NULL }
37 | #define KeyType const void*
38 | #define ConstKeyType KeyType
39 | #define GetKey(value) (value).key
40 | #define InitData(self,value,k) (value).key = (k)
41 | #define Hash(this,key) this->hash_function(key)
42 | #define KeysEqual(this,key1,key2) this->cmp_function(key1, key2)
43 | #define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof(HashSetEntry))
44 | #define EntryIsEmpty(entry) (EntryGetValue(entry).key == NULL)
45 | #define EntryIsDeleted(entry) (EntryGetValue(entry).key == ((void*)-1))
46 |
47 | void cpmap_init_(cpmap_t *map);
48 | #define hashset_init cpmap_init_
49 | void cpmap_init_size_(cpmap_t *map, size_t size);
50 | #define hashset_init_size cpmap_init_size_
51 | #define hashset_destroy cpmap_destroy
52 | cpmap_entry_t *cpmap_insert_(cpmap_t *map, const void *key);
53 | #define hashset_insert cpmap_insert_
54 | #define hashset_remove cpmap_remove
55 | cpmap_entry_t *cpmap_find_(const cpmap_t *map, const void *key);
56 | #define hashset_find cpmap_find_
57 | #define hashset_size cpmap_size
58 | #define hashset_iterator_init cpmap_iterator_init
59 | #define hashset_iterator_next cpmap_iterator_next
60 | #define hashset_remove_iterator cpmap_remove_iterator
61 |
62 | #include "hashset.c.h"
63 |
64 | void cpmap_init(cpmap_t *map, cpmap_hash_function hash_function,
65 | cpmap_cmp_function cmp_function)
66 | {
67 | map->hash_function = hash_function;
68 | map->cmp_function = cmp_function;
69 | cpmap_init_(map);
70 | }
71 |
72 | void cpmap_init_size(cpmap_t *map, cpmap_hash_function hash_function,
73 | cpmap_cmp_function cmp_function, size_t expected_elems)
74 | {
75 | map->hash_function = hash_function;
76 | map->cmp_function = cmp_function;
77 | cpmap_init_size_(map, expected_elems);
78 | }
79 |
80 | void cpmap_set(cpmap_t *map, const void *key, void *data)
81 | {
82 | if (data == NULL) {
83 | cpmap_remove(map, key);
84 | } else {
85 | cpmap_entry_t *entry = cpmap_insert_(map, key);
86 | entry->data = data;
87 | }
88 | }
89 |
90 | void *cpmap_find(const cpmap_t *map, const void *key)
91 | {
92 | cpmap_entry_t *entry = cpmap_find_(map, key);
93 | if (entry == NULL)
94 | return NULL;
95 | return entry->data;
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/src-cpp/adt/cpmap.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @date 16.03.2007
23 | * @brief a pointer to pointer map with a custom compare/hash functions
24 | * @author Matthias Braun
25 | * @version $Id$
26 | */
27 | #ifndef FIRM_ADT_CPMAP_H
28 | #define FIRM_ADT_CPMAP_H
29 |
30 | /**
31 | * The type of a cpmap compare function.
32 | *
33 | * @param p1 pointer to an element
34 | * @param p2 pointer to another element
35 | *
36 | * @return 1 if the elements are identically, zero else
37 | */
38 | typedef int (*cpmap_cmp_function) (const void *p1, const void *p2);
39 |
40 | /**
41 | * The type of a cpmap hash function.
42 | */
43 | typedef unsigned (*cpmap_hash_function) (const void *obj);
44 |
45 | typedef struct cpmap_entry_t {
46 | const void *key;
47 | void *data;
48 | } cpmap_entry_t;
49 |
50 | #define HashSet cpmap_t
51 | #define HashSetIterator cpmap_iterator_t
52 | #define HashSetEntry cpmap_hashset_entry_t
53 | #define ValueType cpmap_entry_t
54 | #define ADDITIONAL_DATA cpmap_cmp_function cmp_function; cpmap_hash_function hash_function;
55 | #include "hashset.h"
56 | #undef ADDITIONAL_DATA
57 | #undef ValueType
58 | #undef HashSetEntry
59 | #undef HashSetIterator
60 | #undef HashSet
61 |
62 | typedef struct cpmap_t cpmap_t;
63 | typedef struct cpmap_iterator_t cpmap_iterator_t;
64 |
65 | /**
66 | * Initializes a cpmap
67 | *
68 | * @param cpmap Pointer to allocated space for the cpmap
69 | * @param hash_function The hash function to use
70 | * @param cmp_function The compare function to use
71 | */
72 | void cpmap_init(cpmap_t *cpmap, cpmap_hash_function hash_function,
73 | cpmap_cmp_function cmp_function);
74 |
75 | /**
76 | * Initializes a cpmap
77 | *
78 | * @param cpmap Pointer to allocated space for the cpmap
79 | * @param hash_function The hash function to use
80 | * @param cmp_function The compare function to use
81 | * @param expected_elements Number of elements expected in the cpmap (roughly)
82 | */
83 | void cpmap_init_size(cpmap_t *cpmap, cpmap_hash_function hash_function,
84 | cpmap_cmp_function cmp_function,
85 | size_t expected_elements);
86 |
87 | /**
88 | * Destroys a cpmap and frees the memory allocated for hashtable. The memory of
89 | * the cpmap itself is not freed.
90 | *
91 | * @param cpmap Pointer to the cpmap
92 | */
93 | void cpmap_destroy(cpmap_t *cpmap);
94 |
95 | /**
96 | * Inserts an element into a cpmap.
97 | *
98 | * @param cpmap Pointer to the cpmap
99 | * @param key key under which we file the data
100 | * @param obj the data (we just store a pointer to it)
101 | * @returns The element itself or a pointer to an existing element
102 | */
103 | void cpmap_set(cpmap_t *cpmap, const void *key, void *data);
104 |
105 | /**
106 | * Removes an element from a cpmap. Does nothing if the cpmap doesn't contain
107 | * the element.
108 | *
109 | * @param cpmap Pointer to the cpmap
110 | * @param key key of the data to remove
111 | */
112 | void cpmap_remove(cpmap_t *cpmap, const void *key);
113 |
114 | /**
115 | * Tests whether a cpmap contains a pointer
116 | *
117 | * @param cpmap Pointer to the cpmap
118 | * @param key Key of the data to find
119 | * @returns The data or NULL if not found
120 | */
121 | void *cpmap_find(const cpmap_t *cpmap, const void *key);
122 |
123 | /**
124 | * Returns the number of pointers contained in the cpmap
125 | *
126 | * @param cpmap Pointer to the cpmap
127 | * @returns Number of pointers contained in the cpmap
128 | */
129 | size_t cpmap_size(const cpmap_t *cpmap);
130 |
131 | /**
132 | * Initializes a cpmap iterator. Sets the iterator before the first element in
133 | * the cpmap.
134 | *
135 | * @param iterator Pointer to already allocated iterator memory
136 | * @param cpmap Pointer to the cpmap
137 | */
138 | void cpmap_iterator_init(cpmap_iterator_t *iterator, const cpmap_t *cpmap);
139 |
140 | /**
141 | * Advances the iterator and returns the current element or NULL if all elements
142 | * in the cpmap have been processed.
143 | * @attention It is not allowed to use cpmap_set or cpmap_remove while
144 | * iterating over a cpmap.
145 | *
146 | * @param iterator Pointer to the cpmap iterator.
147 | * @returns Next element in the cpmap or NULL
148 | */
149 | cpmap_entry_t cpmap_iterator_next(cpmap_iterator_t *iterator);
150 |
151 | /**
152 | * Removed the element the iterator currently points to
153 | *
154 | * @param cpmap Pointer to the cpmap
155 | * @param iterator Pointer to the cpmap iterator.
156 | */
157 | void cpmap_remove_iterator(cpmap_t *cpmap, const cpmap_iterator_t *iterator);
158 |
159 | #endif
160 |
--------------------------------------------------------------------------------
/src-cpp/adt/cpset.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief Custom pointer set
23 | * @author Matthias Braun
24 | * @version $Id: cpset.c 17143 2008-01-02 20:56:33Z beck $
25 | *
26 | * This implements a set of pointers which allows to specify custom callbacks
27 | * for comparing and hashing it's elements.
28 | */
29 | #include "cpset.h"
30 |
31 | #define HashSet cpset_t
32 | #define HashSetIterator cpset_iterator_t
33 | #define HashSetEntry cpset_hashset_entry_t
34 | #define ValueType void*
35 | #define NullValue NULL
36 | #define DeletedValue ((void*)-1)
37 | #define Hash(this,key) this->hash_function(key)
38 | #define KeysEqual(this,key1,key2) this->cmp_function(key1, key2)
39 | #define SCALAR_RETURN
40 | #define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof(cpset_hashset_entry_t))
41 |
42 | void cpset_init_(cpset_t *set);
43 | #define hashset_init cpset_init_
44 | void cpset_init_size_(cpset_t *set, size_t size);
45 | #define hashset_init_size cpset_init_size_
46 | #define hashset_destroy cpset_destroy
47 | #define hashset_insert cpset_insert
48 | #define hashset_remove cpset_remove
49 | #define hashset_find cpset_find
50 | #define hashset_size cpset_size
51 | #define hashset_iterator_init cpset_iterator_init
52 | #define hashset_iterator_next cpset_iterator_next
53 | #define hashset_remove_iterator cpset_remove_iterator
54 |
55 | #include "hashset.c.h"
56 |
57 | void cpset_init(cpset_t *set, cpset_hash_function hash_function,
58 | cpset_cmp_function cmp_function)
59 | {
60 | set->hash_function = hash_function;
61 | set->cmp_function = cmp_function;
62 | cpset_init_(set);
63 | }
64 |
65 | void cpset_init_size(cpset_t *set, cpset_hash_function hash_function,
66 | cpset_cmp_function cmp_function, size_t expected_elems)
67 | {
68 | set->hash_function = hash_function;
69 | set->cmp_function = cmp_function;
70 | cpset_init_size_(set, expected_elems);
71 | }
72 |
--------------------------------------------------------------------------------
/src-cpp/adt/cpset.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @date 16.03.2007
23 | * @brief a set of pointers with a custom compare function
24 | * @author Matthias Braun
25 | * @version $Id: cpset.h 26416 2009-08-24 16:50:07Z buchwald $
26 | */
27 | #ifndef FIRM_ADT_CPSET_H
28 | #define FIRM_ADT_CPSET_H
29 |
30 | /**
31 | * The type of a cpset compare function.
32 | *
33 | * @param p1 pointer to an element
34 | * @param p2 pointer to another element
35 | *
36 | * @return 1 if the elements are identically, zero else
37 | */
38 | typedef int (*cpset_cmp_function) (const void *p1, const void *p2);
39 |
40 | /**
41 | * The type of a cpset hash function.
42 | */
43 | typedef unsigned (*cpset_hash_function) (const void *obj);
44 |
45 | #define HashSet cpset_t
46 | #define HashSetIterator cpset_iterator_t
47 | #define HashSetEntry cpset_hashset_entry_t
48 | #define ValueType void*
49 | #define ADDITIONAL_DATA cpset_cmp_function cmp_function; cpset_hash_function hash_function;
50 | #include "hashset.h"
51 | #undef ADDITIONAL_DATA
52 | #undef ValueType
53 | #undef HashSetEntry
54 | #undef HashSetIterator
55 | #undef HashSet
56 |
57 | typedef struct cpset_t cpset_t;
58 | typedef struct cpset_iterator_t cpset_iterator_t;
59 |
60 | /**
61 | * Initializes a cpset
62 | *
63 | * @param cpset Pointer to allocated space for the cpset
64 | * @param hash_function The hash function to use
65 | * @param cmp_function The compare function to use
66 | */
67 | void cpset_init(cpset_t *cpset, cpset_hash_function hash_function,
68 | cpset_cmp_function cmp_function);
69 |
70 | /**
71 | * Initializes a cpset
72 | *
73 | * @param cpset Pointer to allocated space for the cpset
74 | * @param hash_function The hash function to use
75 | * @param cmp_function The compare function to use
76 | * @param expected_elements Number of elements expected in the cpset (roughly)
77 | */
78 | void cpset_init_size(cpset_t *cpset, cpset_hash_function hash_function,
79 | cpset_cmp_function cmp_function,
80 | size_t expected_elements);
81 |
82 | /**
83 | * Destroys a cpset and frees the memory allocated for hashtable. The memory of
84 | * the cpset itself is not freed.
85 | *
86 | * @param cpset Pointer to the cpset
87 | */
88 | void cpset_destroy(cpset_t *cpset);
89 |
90 | /**
91 | * Inserts an element into a cpset.
92 | *
93 | * @param cpset Pointer to the cpset
94 | * @param obj Element to insert into the cpset
95 | * @returns The element itself or a pointer to an existing element
96 | */
97 | void* cpset_insert(cpset_t *cpset, void *obj);
98 |
99 | /**
100 | * Removes an element from a cpset. Does nothing if the cpset doesn't contain the
101 | * element.
102 | *
103 | * @param cpset Pointer to the cpset
104 | * @param obj Pointer to remove from the cpset
105 | */
106 | void cpset_remove(cpset_t *cpset, const void *obj);
107 |
108 | /**
109 | * Tests whether a cpset contains a pointer
110 | *
111 | * @param cpset Pointer to the cpset
112 | * @param obj The pointer to find
113 | * @returns An equivalent object to @p obj or NULL
114 | */
115 | void *cpset_find(const cpset_t *cpset, const void *obj);
116 |
117 | /**
118 | * Returns the number of pointers contained in the cpset
119 | *
120 | * @param cpset Pointer to the cpset
121 | * @returns Number of pointers contained in the cpset
122 | */
123 | size_t cpset_size(const cpset_t *cpset);
124 |
125 | /**
126 | * Initializes a cpset iterator. Sets the iterator before the first element in
127 | * the cpset.
128 | *
129 | * @param iterator Pointer to already allocated iterator memory
130 | * @param cpset Pointer to the cpset
131 | */
132 | void cpset_iterator_init(cpset_iterator_t *iterator, const cpset_t *cpset);
133 |
134 | /**
135 | * Advances the iterator and returns the current element or NULL if all elements
136 | * in the cpset have been processed.
137 | * @attention It is not allowed to use cpset_insert or cpset_remove while
138 | * iterating over a cpset.
139 | *
140 | * @param iterator Pointer to the cpset iterator.
141 | * @returns Next element in the cpset or NULL
142 | */
143 | void *cpset_iterator_next(cpset_iterator_t *iterator);
144 |
145 | /**
146 | * Removed the element the iterator currently points to
147 | *
148 | * @param cpset Pointer to the cpset
149 | * @param iterator Pointer to the cpset iterator.
150 | */
151 | void cpset_remove_iterator(cpset_t *cpset, const cpset_iterator_t *iterator);
152 |
153 | #endif /* FIRM_ADT_CPSET_H */
154 |
--------------------------------------------------------------------------------
/src-cpp/adt/error.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of cparser.
3 | * Copyright (C) 2007-2009 Matthias Braun
4 | *
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 | * 02111-1307, USA.
19 | */
20 | #include
21 | #include
22 | #include
23 |
24 | static inline __attribute__((noreturn, format(printf, 1, 2)))
25 | void panic(const char *fmt, ...)
26 | {
27 | va_list ap;
28 | va_start(ap, fmt);
29 | fputs("Panic: ", stderr);
30 | vfprintf(stderr, fmt, ap);
31 | fputc('\n', stderr);
32 | va_end(ap);
33 |
34 | abort();
35 | }
36 |
--------------------------------------------------------------------------------
/src-cpp/adt/fourcc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief Define the famous infame FOURCC macro.
23 | * @date 02.01.2004
24 | * @version $Id: fourcc.h 17143 2008-01-02 20:56:33Z beck $
25 | */
26 | #ifndef FIRM_ADT_FOURCC_H
27 | #define FIRM_ADT_FOURCC_H
28 |
29 | /** define a readable fourcc code */
30 | #define FOURCC(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/src-cpp/adt/hashptr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief Hash function for pointers
23 | * @author Michael Beck, Sebastian Hack
24 | * @version $Id: hashptr.h 26956 2010-01-13 15:41:28Z matze $
25 | */
26 | #ifndef FIRM_ADT_HASHPTR_H
27 | #define FIRM_ADT_HASHPTR_H
28 |
29 | #define _FIRM_FNV_OFFSET_BASIS 2166136261U
30 | #define _FIRM_FNV_FNV_PRIME 16777619U
31 |
32 | /* Computing x * _FIRM_FNV_FNV_PRIME */
33 | #define _FIRM_FNV_TIMES_PRIME(x) ((x) * _FIRM_FNV_FNV_PRIME)
34 |
35 | static inline unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes)
36 | {
37 | unsigned i;
38 | unsigned hash = _FIRM_FNV_OFFSET_BASIS;
39 |
40 | for(i = 0; i < bytes; ++i) {
41 | hash = _FIRM_FNV_TIMES_PRIME(hash);
42 | hash ^= data[i];
43 | }
44 |
45 | return hash;
46 | }
47 |
48 | static inline unsigned firm_fnv_hash_str(const char *data)
49 | {
50 | unsigned i;
51 | unsigned hash = _FIRM_FNV_OFFSET_BASIS;
52 |
53 | for(i = 0; data[i] != '\0'; ++i) {
54 | hash = _FIRM_FNV_TIMES_PRIME(hash);
55 | hash ^= data[i];
56 | }
57 |
58 | return hash;
59 | }
60 |
61 | /**
62 | * hash a pointer value: Pointer addresses are mostly aligned to 4
63 | * or 8 bytes. So we remove the lowest 3 bits
64 | */
65 | #define HASH_PTR(ptr) ((unsigned)(((char *) (ptr) - (char *)0) >> 3))
66 |
67 | static inline unsigned hash_ptr(const void *ptr)
68 | {
69 | return HASH_PTR(ptr);
70 | }
71 |
72 | /**
73 | * Hash a string.
74 | * @param str The string (can be const).
75 | * @param len The length of the string.
76 | * @return A hash value for the string.
77 | */
78 | #define HASH_STR(str,len) firm_fnv_hash((const unsigned char *) (str), (len))
79 |
80 | #ifdef _MSC_VER
81 | #pragma warning(disable:4307)
82 | #endif /* _MSC_VER */
83 |
84 | static inline unsigned _hash_combine(unsigned x, unsigned y)
85 | {
86 | unsigned hash = _FIRM_FNV_TIMES_PRIME(_FIRM_FNV_OFFSET_BASIS);
87 | hash ^= x;
88 | hash = _FIRM_FNV_TIMES_PRIME(hash);
89 | hash ^= y;
90 | return hash;
91 | }
92 |
93 | #ifdef _MSC_VER
94 | #pragma warning(default:4307)
95 | #endif /* _MSC_VER */
96 |
97 | /**
98 | * Make one hash value out of two others.
99 | * @param a One hash value.
100 | * @param b Another hash value.
101 | * @return A hash value computed from the both.
102 | */
103 | #define HASH_COMBINE(a,b) _hash_combine(a, b)
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/src-cpp/adt/hashset.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of libFirm.
3 | * Copyright (C) 2012 University of Karlsruhe.
4 | */
5 |
6 | /**
7 | * @file
8 | * @date 16.03.2007
9 | * @brief Generic hashset functions
10 | * @author Matthias Braun
11 | *
12 | * You have to specialize this header by defining HashSet, HashSetIterator and
13 | * ValueType
14 | */
15 | #ifdef HashSet
16 |
17 | #include
18 |
19 | #ifdef DO_REHASH
20 | #define HashSetEntry ValueType
21 | #else
22 | typedef struct HashSetEntry {
23 | ValueType data;
24 | unsigned hash;
25 | } HashSetEntry;
26 | #endif
27 |
28 | struct HashSet {
29 | HashSetEntry *entries;
30 | size_t num_buckets;
31 | size_t enlarge_threshold;
32 | size_t shrink_threshold;
33 | size_t num_elements;
34 | size_t num_deleted;
35 | int consider_shrink;
36 | #ifndef NDEBUG
37 | unsigned entries_version;
38 | #endif
39 | #ifdef ADDITIONAL_DATA
40 | ADDITIONAL_DATA
41 | #endif
42 | };
43 |
44 | #ifdef HashSetIterator
45 | struct HashSetIterator {
46 | HashSetEntry *current_bucket;
47 | HashSetEntry *end;
48 | #ifndef NDEBUG
49 | const struct HashSet *set;
50 | unsigned entries_version;
51 | #endif
52 | };
53 | #endif
54 |
55 | #ifdef DO_REHASH
56 | #undef HashSetEntry
57 | #endif
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/src-cpp/adt/obst.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of cparser.
3 | * Copyright (C) 2007-2009 Matthias Braun
4 | *
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 | * 02111-1307, USA.
19 | */
20 | #include "obstack.h"
21 | #include "xmalloc.h"
22 |
23 | #define obstack_chunk_alloc xmalloc
24 | #define obstack_chunk_free free
25 |
--------------------------------------------------------------------------------
/src-cpp/adt/obstack.c:
--------------------------------------------------------------------------------
1 | /* obstack.c - subroutines used implicitly by object stack macros
2 | Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
3 | 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 | This file is part of the GNU C Library.
5 |
6 | The GNU C Library is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU Lesser General Public
8 | License as published by the Free Software Foundation; either
9 | version 2.1 of the License, or (at your option) any later version.
10 |
11 | The GNU C Library is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public
17 | License along with the GNU C Library; if not, write to the Free
18 | Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 | Boston, MA 02110-1301, USA. */
20 | #include "obstack.h"
21 |
22 | /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
23 | incremented whenever callers compiled using an old obstack.h can no
24 | longer properly call the functions in this obstack.c. */
25 | #define OBSTACK_INTERFACE_VERSION 1
26 |
27 | #include /* Random thing to get __GNU_LIBRARY__. */
28 | #include
29 | #include
30 |
31 | /* Determine default alignment. */
32 | union fooround
33 | {
34 | uintmax_t i;
35 | long double d;
36 | void *p;
37 | };
38 | struct fooalign
39 | {
40 | char c;
41 | union fooround u;
42 | };
43 | /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
44 | But in fact it might be less smart and round addresses to as much as
45 | DEFAULT_ROUNDING. So we prepare for it to do that. */
46 | enum
47 | {
48 | DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
49 | DEFAULT_ROUNDING = sizeof (union fooround)
50 | };
51 |
52 | /* When we copy a long block of data, this is the unit to do it with.
53 | On some machines, copying successive ints does not work;
54 | in such a case, redefine COPYING_UNIT to `long' (if that works)
55 | or `char' as a last resort. */
56 | # ifndef COPYING_UNIT
57 | # define COPYING_UNIT int
58 | # endif
59 |
60 |
61 | /* The functions allocating more room by calling `obstack_chunk_alloc'
62 | jump to the handler pointed to by `obstack_alloc_failed_handler'.
63 | This can be set to a user defined function which should either
64 | abort gracefully or use longjump - but shouldn't return. This
65 | variable by default points to the internal function
66 | `print_and_abort'. */
67 | static void print_and_abort (void);
68 | void (*obstack_alloc_failed_handler) (void) = print_and_abort;
69 |
70 | /* Exit value used when `print_and_abort' is used. */
71 | # include
72 | int obstack_exit_failure = EXIT_FAILURE;
73 |
74 | /* Define a macro that either calls functions with the traditional malloc/free
75 | calling interface, or calls functions with the mmalloc/mfree interface
76 | (that adds an extra first argument), based on the state of use_extra_arg.
77 | For free, do not use ?:, since some compilers, like the MIPS compilers,
78 | do not allow (expr) ? void : void. */
79 |
80 | # define CALL_CHUNKFUN(h, size) \
81 | (((h) -> use_extra_arg) \
82 | ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
83 | : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
84 |
85 | # define CALL_FREEFUN(h, old_chunk) \
86 | do { \
87 | if ((h) -> use_extra_arg) \
88 | (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
89 | else \
90 | (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
91 | } while (0)
92 |
93 |
94 | /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
95 | Objects start on multiples of ALIGNMENT (0 means use default).
96 | CHUNKFUN is the function to use to allocate chunks,
97 | and FREEFUN the function to free them.
98 |
99 | Return nonzero if successful, calls obstack_alloc_failed_handler if
100 | allocation fails. */
101 |
102 | int
103 | _obstack_begin (struct obstack *h,
104 | int size, int alignment,
105 | void *(*chunkfun) (long),
106 | void (*freefun) (void *))
107 | {
108 | register struct _obstack_chunk *chunk; /* points to new chunk */
109 |
110 | if (alignment == 0)
111 | alignment = DEFAULT_ALIGNMENT;
112 | if (size == 0)
113 | /* Default size is what GNU malloc can fit in a 4096-byte block. */
114 | {
115 | /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
116 | Use the values for range checking, because if range checking is off,
117 | the extra bytes won't be missed terribly, but if range checking is on
118 | and we used a larger request, a whole extra 4096 bytes would be
119 | allocated.
120 |
121 | These number are irrelevant to the new GNU malloc. I suspect it is
122 | less sensitive to the size of the request. */
123 | int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
124 | + 4 + DEFAULT_ROUNDING - 1)
125 | & ~(DEFAULT_ROUNDING - 1));
126 | size = 4096 - extra;
127 | }
128 |
129 | h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
130 | h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
131 | h->chunk_size = size;
132 | h->alignment_mask = alignment - 1;
133 | h->use_extra_arg = 0;
134 |
135 | chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
136 | if (!chunk)
137 | (*obstack_alloc_failed_handler) ();
138 | h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
139 | alignment - 1);
140 | h->chunk_limit = chunk->limit
141 | = (char *) chunk + h->chunk_size;
142 | chunk->prev = 0;
143 | /* The initial chunk now contains no empty object. */
144 | h->maybe_empty_object = 0;
145 | h->alloc_failed = 0;
146 | return 1;
147 | }
148 |
149 | int
150 | _obstack_begin_1 (struct obstack *h, int size, int alignment,
151 | void *(*chunkfun) (void *, long),
152 | void (*freefun) (void *, void *),
153 | void *arg)
154 | {
155 | register struct _obstack_chunk *chunk; /* points to new chunk */
156 |
157 | if (alignment == 0)
158 | alignment = DEFAULT_ALIGNMENT;
159 | if (size == 0)
160 | /* Default size is what GNU malloc can fit in a 4096-byte block. */
161 | {
162 | /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
163 | Use the values for range checking, because if range checking is off,
164 | the extra bytes won't be missed terribly, but if range checking is on
165 | and we used a larger request, a whole extra 4096 bytes would be
166 | allocated.
167 |
168 | These number are irrelevant to the new GNU malloc. I suspect it is
169 | less sensitive to the size of the request. */
170 | int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
171 | + 4 + DEFAULT_ROUNDING - 1)
172 | & ~(DEFAULT_ROUNDING - 1));
173 | size = 4096 - extra;
174 | }
175 |
176 | h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
177 | h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
178 | h->chunk_size = size;
179 | h->alignment_mask = alignment - 1;
180 | h->extra_arg = arg;
181 | h->use_extra_arg = 1;
182 |
183 | chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
184 | if (!chunk)
185 | (*obstack_alloc_failed_handler) ();
186 | h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
187 | alignment - 1);
188 | h->chunk_limit = chunk->limit
189 | = (char *) chunk + h->chunk_size;
190 | chunk->prev = 0;
191 | /* The initial chunk now contains no empty object. */
192 | h->maybe_empty_object = 0;
193 | h->alloc_failed = 0;
194 | return 1;
195 | }
196 |
197 | /* Allocate a new current chunk for the obstack *H
198 | on the assumption that LENGTH bytes need to be added
199 | to the current object, or a new object of length LENGTH allocated.
200 | Copies any partial object from the end of the old chunk
201 | to the beginning of the new one. */
202 |
203 | void
204 | _obstack_newchunk (struct obstack *h, int length)
205 | {
206 | register struct _obstack_chunk *old_chunk = h->chunk;
207 | register struct _obstack_chunk *new_chunk;
208 | register long new_size;
209 | register long obj_size = h->next_free - h->object_base;
210 | register long i;
211 | long already;
212 | char *object_base;
213 |
214 | /* Compute size for new chunk. */
215 | new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
216 | if (new_size < h->chunk_size)
217 | new_size = h->chunk_size;
218 |
219 | /* Allocate and initialize the new chunk. */
220 | new_chunk = CALL_CHUNKFUN (h, new_size);
221 | if (!new_chunk)
222 | (*obstack_alloc_failed_handler) ();
223 | h->chunk = new_chunk;
224 | new_chunk->prev = old_chunk;
225 | new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
226 |
227 | /* Compute an aligned object_base in the new chunk */
228 | object_base =
229 | __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
230 |
231 | /* Move the existing object to the new chunk.
232 | Word at a time is fast and is safe if the object
233 | is sufficiently aligned. */
234 | if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
235 | {
236 | for (i = obj_size / sizeof (COPYING_UNIT) - 1;
237 | i >= 0; i--)
238 | ((COPYING_UNIT *)object_base)[i]
239 | = ((COPYING_UNIT *)h->object_base)[i];
240 | /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
241 | but that can cross a page boundary on a machine
242 | which does not do strict alignment for COPYING_UNITS. */
243 | already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
244 | }
245 | else
246 | already = 0;
247 | /* Copy remaining bytes one by one. */
248 | for (i = already; i < obj_size; i++)
249 | object_base[i] = h->object_base[i];
250 |
251 | /* If the object just copied was the only data in OLD_CHUNK,
252 | free that chunk and remove it from the chain.
253 | But not if that chunk might contain an empty object. */
254 | if (! h->maybe_empty_object
255 | && (h->object_base
256 | == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
257 | h->alignment_mask)))
258 | {
259 | new_chunk->prev = old_chunk->prev;
260 | CALL_FREEFUN (h, old_chunk);
261 | }
262 |
263 | h->object_base = object_base;
264 | h->next_free = h->object_base + obj_size;
265 | /* The new chunk certainly contains no empty object yet. */
266 | h->maybe_empty_object = 0;
267 | }
268 |
269 | /* Return nonzero if object OBJ has been allocated from obstack H.
270 | This is here for debugging.
271 | If you use it in a program, you are probably losing. */
272 |
273 | /* Suppress -Wmissing-prototypes warning. We don't want to declare this in
274 | obstack.h because it is just for debugging. */
275 | int _obstack_allocated_p (struct obstack *h, void *obj);
276 |
277 | int
278 | _obstack_allocated_p (struct obstack *h, void *obj)
279 | {
280 | register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
281 | register struct _obstack_chunk *plp; /* point to previous chunk if any */
282 |
283 | lp = (h)->chunk;
284 | /* We use >= rather than > since the object cannot be exactly at
285 | the beginning of the chunk but might be an empty object exactly
286 | at the end of an adjacent chunk. */
287 | while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
288 | {
289 | plp = lp->prev;
290 | lp = plp;
291 | }
292 | return lp != 0;
293 | }
294 |
295 | /* Free objects in obstack H, including OBJ and everything allocate
296 | more recently than OBJ. If OBJ is zero, free everything in H. */
297 |
298 | # undef obstack_free
299 |
300 | void
301 | obstack_free (struct obstack *h, void *obj)
302 | {
303 | register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
304 | register struct _obstack_chunk *plp; /* point to previous chunk if any */
305 |
306 | lp = h->chunk;
307 | /* We use >= because there cannot be an object at the beginning of a chunk.
308 | But there can be an empty object at that address
309 | at the end of another chunk. */
310 | while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
311 | {
312 | plp = lp->prev;
313 | CALL_FREEFUN (h, lp);
314 | lp = plp;
315 | /* If we switch chunks, we can't tell whether the new current
316 | chunk contains an empty object, so assume that it may. */
317 | h->maybe_empty_object = 1;
318 | }
319 | if (lp)
320 | {
321 | h->object_base = h->next_free = (char *) (obj);
322 | h->chunk_limit = lp->limit;
323 | h->chunk = lp;
324 | }
325 | else if (obj != 0)
326 | /* obj is not in any of the chunks! */
327 | abort ();
328 | }
329 |
330 | int
331 | _obstack_memory_used (struct obstack *h)
332 | {
333 | register struct _obstack_chunk* lp;
334 | register int nbytes = 0;
335 |
336 | for (lp = h->chunk; lp != 0; lp = lp->prev)
337 | {
338 | nbytes += lp->limit - (char *) lp;
339 | }
340 | return nbytes;
341 | }
342 |
343 | static void
344 | __attribute__ ((noreturn))
345 | print_and_abort (void)
346 | {
347 | /* Don't change any of these strings. Yes, it would be possible to add
348 | the newline to the string and use fputs or so. But this must not
349 | happen because the "memory exhausted" message appears in other places
350 | like this and the translation should be reused instead of creating
351 | a very similar string which requires a separate translation. */
352 | fprintf (stderr, "%s\n", "memory exhausted");
353 | exit (obstack_exit_failure);
354 | }
355 |
--------------------------------------------------------------------------------
/src-cpp/adt/obstack_printf.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of cparser.
3 | * Copyright (C) 2007-2009 Matthias Braun
4 | *
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 | * 02111-1307, USA.
19 | */
20 | #include
21 | #include
22 | #include "obstack.h"
23 |
24 | int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap)
25 | {
26 | /* currently a poor implementation ... */
27 | char buf[1024];
28 | int len;
29 |
30 | len = vsnprintf(buf, sizeof(buf), fmt, ap);
31 | obstack_grow(obst, buf, len);
32 |
33 | return len;
34 | }
35 |
36 | int obstack_printf(struct obstack *obst, const char *fmt, ...)
37 | {
38 | va_list ap;
39 | int len;
40 |
41 | va_start(ap, fmt);
42 | len = obstack_vprintf(obst, fmt, ap);
43 | va_end(ap);
44 |
45 | return len;
46 | }
47 |
--------------------------------------------------------------------------------
/src-cpp/adt/pdeq.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief double ended queue of generic pointers.
23 | * @author Christian von Roques
24 | * @date 1999 by getting from fiasco
25 | * @version $Id: pdeq.c 24125 2008-11-28 16:00:39Z mallon $
26 | */
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include "fourcc.h"
33 | #include "pdeq.h"
34 | #include "xmalloc.h"
35 | #include "align.h"
36 |
37 | /* Pointer Double Ended Queue */
38 | #define PDEQ_MAGIC1 FOURCC('P','D','E','1')
39 | #define PDEQ_MAGIC2 FOURCC('P','D','E','2')
40 |
41 | /** Size of pdeq block cache. */
42 | #define TUNE_NSAVED_PDEQS 16
43 |
44 | /**
45 | * Maximal number of data items in a pdeq chunk.
46 | */
47 | #define NDATA ((int)((PREF_MALLOC_SIZE - offsetof (pdeq, data)) / sizeof (void *)))
48 |
49 | #ifdef NDEBUG
50 | # define VRFY(dq) ((void)0)
51 | #else
52 | # define VRFY(dq) assert((dq) && ((dq)->magic == PDEQ_MAGIC1))
53 | #endif
54 |
55 | /**
56 | * A pointer double ended queue.
57 | * This structure is used as a list chunk either.
58 | */
59 | struct pdeq {
60 | #ifndef NDEBUG
61 | unsigned magic; /**< debug magic */
62 | #endif
63 | pdeq *l_end, *r_end; /**< left and right ends of the queue */
64 | pdeq *l, *r; /**< left and right neighbor */
65 | int n; /**< number of elements in the current chunk */
66 | int p; /**< the read/write pointer */
67 | const void *data[1]; /**< storage for elements */
68 | };
69 |
70 |
71 | /**
72 | * cache of unused, pdeq blocks to speed up new_pdeq and del_pdeq.
73 | * +1 for compilers that can't grok empty arrays
74 | */
75 | static pdeq *pdeq_block_cache[TUNE_NSAVED_PDEQS+1];
76 |
77 | /**
78 | * Number of pdeqs in pdeq_store.
79 | */
80 | static unsigned pdeqs_cached;
81 |
82 | /**
83 | * Free a pdeq chunk, put in into the cache if possible.
84 | *
85 | * @param p The pdeq chunk.
86 | */
87 | static inline void free_pdeq_block (pdeq *p)
88 | {
89 | #ifndef NDEBUG
90 | p->magic = 0xbadf00d1;
91 | #endif
92 | if (pdeqs_cached < TUNE_NSAVED_PDEQS) {
93 | pdeq_block_cache[pdeqs_cached++] = p;
94 | } else {
95 | xfree (p);
96 | }
97 | }
98 |
99 | /**
100 | * Allocate a new pdeq chunk, get it from the cache if possible.
101 | *
102 | * @return A new pdeq chunk.
103 | */
104 | static inline pdeq *alloc_pdeq_block (void)
105 | {
106 | pdeq *p;
107 | if (TUNE_NSAVED_PDEQS && pdeqs_cached) {
108 | p = pdeq_block_cache[--pdeqs_cached];
109 | } else {
110 | p = xmalloc(PREF_MALLOC_SIZE);
111 | }
112 | return p;
113 | }
114 |
115 |
116 | #ifndef NDEBUG
117 | /**
118 | * Verify a double ended list, assert if failure.
119 | *
120 | * @param dq The list to verify.
121 | */
122 | void _pdeq_vrfy(pdeq *dq)
123 | {
124 | pdeq *q;
125 |
126 | assert ( dq
127 | && (dq->magic == PDEQ_MAGIC1)
128 | && (dq->l_end && dq->r_end));
129 | q = dq->l_end;
130 | while (q) {
131 | assert ( ((q == dq) || (q->magic == PDEQ_MAGIC2))
132 | && ((q == dq->l_end) ^ (q->l != NULL))
133 | && ((q == dq->r_end) ^ (q->r != NULL))
134 | && (!q->l || (q == q->l->r))
135 | && ((q->n >= 0) && (q->n <= NDATA))
136 | && ((q == dq->l_end) || (q == dq->r_end) || (q->n == NDATA))
137 | && ((q->p >= 0) && (q->p < NDATA)));
138 | q = q->r;
139 | }
140 | }
141 | #endif
142 |
143 | /* Creates a new double ended pointer list. */
144 | pdeq *new_pdeq(void)
145 | {
146 | pdeq *dq;
147 |
148 | dq = alloc_pdeq_block();
149 |
150 | #ifndef NDEBUG
151 | dq->magic = PDEQ_MAGIC1;
152 | #endif
153 | dq->l_end = dq->r_end = dq;
154 | dq->l = dq->r = NULL;
155 | dq->n = dq->p = 0;
156 |
157 | VRFY(dq);
158 | return dq;
159 | }
160 |
161 | /* Creates a new double ended pointer list and puts an initial pointer element in. */
162 | pdeq *new_pdeq1(const void *x)
163 | {
164 | return pdeq_putr(new_pdeq(), x);
165 | }
166 |
167 | /* Delete a double ended pointer list. */
168 | void del_pdeq(pdeq *dq)
169 | {
170 | pdeq *q, *qq;
171 |
172 | VRFY(dq);
173 |
174 | q = dq->l_end; /* left end of chain */
175 | /* pdeq trunk empty, but !pdeq_empty() ==> trunk not in chain */
176 | if (dq->n == 0 && dq->l_end != dq ) {
177 | free_pdeq_block(dq);
178 | }
179 |
180 | /* Free all blocks in the pdeq chain */
181 | do {
182 | qq = q->r;
183 | free_pdeq_block(q);
184 | } while ((q = qq));
185 |
186 | }
187 |
188 | /* Checks if a list is empty. */
189 | int pdeq_empty(pdeq *dq)
190 | {
191 | VRFY(dq);
192 | return dq->l_end->n == 0;
193 | }
194 |
195 | /* Returns the length of a double ended pointer list. */
196 | int pdeq_len(pdeq *dq)
197 | {
198 | int n;
199 | pdeq *q;
200 |
201 | VRFY(dq);
202 |
203 | n = 0;
204 | q = dq->l_end;
205 | do {
206 | n += q->n;
207 | q = q->r;
208 | } while (q);
209 |
210 | return n;
211 | }
212 |
213 | /* Add a pointer to the right site of a double ended pointer list. */
214 | pdeq *pdeq_putr(pdeq *dq, const void *x)
215 | {
216 | pdeq *rdq;
217 | int n;
218 |
219 | VRFY(dq);
220 |
221 | rdq = dq->r_end;
222 | if (rdq->n >= NDATA) { /* tailblock full */
223 | pdeq *ndq;
224 |
225 | ndq = dq; /* try to reuse trunk, but ... */
226 | if (dq->n) { /* ... if trunk used */
227 | /* allocate and init new block */
228 | ndq = alloc_pdeq_block();
229 | #ifndef NDEBUG
230 | ndq->magic = PDEQ_MAGIC2;
231 | #endif
232 | ndq->l_end = ndq->r_end = NULL;
233 | }
234 |
235 | ndq->r = NULL;
236 | ndq->l = rdq; rdq->r = ndq;
237 | ndq->n = 0; ndq->p = 0;
238 | dq->r_end = ndq;
239 | rdq = ndq;
240 | }
241 |
242 | n = rdq->n++ + rdq->p;
243 | if (n >= NDATA) n -= NDATA;
244 |
245 | rdq->data[n] = x;
246 |
247 | VRFY(dq);
248 | return dq;
249 | }
250 |
251 | /* Add a pointer to the left site of a double ended pointer list. */
252 | pdeq *pdeq_putl(pdeq *dq, const void *x)
253 | {
254 | pdeq *ldq;
255 | int p;
256 |
257 | VRFY(dq);
258 |
259 | ldq = dq->l_end;
260 | if (ldq->n >= NDATA) { /* headblock full */
261 | pdeq *ndq;
262 |
263 | ndq = dq; /* try to reuse trunk, but ... */
264 | if (dq->n) { /* ... if trunk used */
265 | /* allocate and init new block */
266 | ndq = alloc_pdeq_block();
267 | #ifndef NDEBUG
268 | ndq->magic = PDEQ_MAGIC2;
269 | #endif
270 | ndq->l_end = ndq->r_end = NULL;
271 | }
272 |
273 | ndq->l = NULL;
274 | ndq->r = ldq; ldq->l = ndq;
275 | ndq->n = 0; ndq->p = 0;
276 | dq->l_end = ndq;
277 | ldq = ndq;
278 | }
279 |
280 | ldq->n++;
281 | p = ldq->p - 1;
282 | if (p < 0) p += NDATA;
283 | ldq->p = p;
284 |
285 | ldq->data[p] = x;
286 |
287 | VRFY(dq);
288 | return dq;
289 | }
290 |
291 | /* Retrieve a pointer from the right site of a double ended pointer list. */
292 | void *pdeq_getr(pdeq *dq)
293 | {
294 | pdeq *rdq;
295 | const void *x;
296 | int n;
297 |
298 | VRFY(dq);
299 | assert(dq->l_end->n);
300 |
301 | rdq = dq->r_end;
302 | n = rdq->p + --rdq->n;
303 | if (n >= NDATA) n -= NDATA;
304 | x = rdq->data[n];
305 |
306 | if (rdq->n == 0) {
307 | if (rdq->l) {
308 | dq->r_end = rdq->l;
309 | rdq->l->r = NULL;
310 | rdq->l = NULL;
311 | } else {
312 | dq->r_end = dq->l_end = dq;
313 | }
314 | if (dq != rdq) {
315 | free_pdeq_block(rdq);
316 | }
317 | }
318 |
319 | VRFY(dq);
320 | return (void *)x;
321 | }
322 |
323 | /* Retrieve a pointer from the left site of a double ended pointer list. */
324 | void *pdeq_getl(pdeq *dq)
325 | {
326 | pdeq *ldq;
327 | const void *x;
328 | int p;
329 |
330 | VRFY(dq);
331 | assert(dq->l_end->n);
332 |
333 | ldq = dq->l_end;
334 | p = ldq->p;
335 | x = ldq->data[p];
336 | if (++p >= NDATA) p = 0;
337 | ldq->p = p;
338 |
339 | if (--ldq->n == 0) {
340 | if (ldq->r) {
341 | dq->l_end = ldq->r;
342 | ldq->r->l = NULL;
343 | ldq->r = NULL;
344 | } else {
345 | dq->l_end = dq->r_end = dq;
346 | }
347 | if (dq != ldq) {
348 | free_pdeq_block(ldq);
349 | }
350 | }
351 |
352 | VRFY(dq);
353 | return (void *)x;
354 | }
355 |
356 | /*
357 | * Returns non-zero if a double ended pointer list
358 | * contains a pointer x.
359 | */
360 | int pdeq_contains(pdeq *dq, const void *x)
361 | {
362 | pdeq *q;
363 |
364 | VRFY(dq);
365 |
366 | q = dq->l_end;
367 | do {
368 | int p, ep;
369 |
370 | p = q->p; ep = p + q->n;
371 |
372 | if (ep > NDATA) {
373 | do {
374 | if (q->data[p] == x) return 1;
375 | } while (++p < NDATA);
376 | p = 0;
377 | ep -= NDATA;
378 | }
379 |
380 | while (p < ep) {
381 | if (q->data[p++] == x) return 1;
382 | }
383 |
384 | q = q->r;
385 | } while (q);
386 |
387 | return 0;
388 | }
389 |
390 | /*
391 | * Search a key in a double ended pointer list, the search
392 | * is controlled by a compare function.
393 | * An element is found, if the compare function returns 0.
394 | * The search is started from the left site of the list.
395 | */
396 | void *pdeq_search(pdeq *dq, cmp_fun cmp, const void *key)
397 | {
398 | pdeq *q;
399 | int p;
400 |
401 | VRFY(dq);
402 |
403 | q = dq->l_end;
404 | do {
405 | int ep;
406 |
407 | p = q->p; ep = p + q->n;
408 |
409 | if (ep > NDATA) {
410 | do {
411 | if (!cmp (q->data[p], key)) return (void *)q->data[p-1];
412 | } while (++p < NDATA);
413 | p = 0;
414 | ep -= NDATA;
415 | }
416 |
417 | while (p < ep) {
418 | if (!cmp (q->data[p++], key)) return (void *)q->data[p-1];
419 | }
420 |
421 | q = q->r;
422 | } while (q);
423 |
424 | return NULL;
425 | }
426 |
427 | /*
428 | * Convert the double ended pointer list into a linear array beginning from
429 | * left, the first element in the linear array will be the left one.
430 | */
431 | void **pdeq_copyl(pdeq *dq, const void **dst)
432 | {
433 | pdeq *q;
434 | const void **d = dst;
435 |
436 | VRFY(dq);
437 |
438 | q = dq->l_end;
439 | while (q) {
440 | int p, n;
441 |
442 | p = q->p; n = q->n;
443 |
444 | if (n + p > NDATA) {
445 | int nn = NDATA - p;
446 | memcpy((void *) d, &q->data[p], nn * sizeof(void *)); d += nn;
447 | p = 0; n -= nn;
448 | }
449 |
450 | memcpy((void *) d, &q->data[p], n * sizeof(void *)); d += n;
451 |
452 | q = q->r;
453 | }
454 |
455 | return (void **)dst;
456 | }
457 |
458 | /*
459 | * Convert the double ended pointer list into a linear array beginning from
460 | * right, the first element in the linear array will be the right one.
461 | */
462 | void **pdeq_copyr(pdeq *dq, const void **dst)
463 | {
464 | pdeq *q;
465 | const void **d = dst;
466 |
467 | VRFY(dq);
468 |
469 | q = dq->r_end;
470 | while (q) {
471 | int p, i;
472 |
473 | p = q->p; i = q->n + p - 1;
474 | if (i >= NDATA) {
475 | i -= NDATA;
476 | do *d++ = q->data[i]; while (--i >= 0);
477 | i = NDATA - 1;
478 | }
479 |
480 | do *d++ = q->data[i]; while (--i >= p);
481 |
482 | q = q->l;
483 | }
484 |
485 | return (void **)dst;
486 | }
487 |
--------------------------------------------------------------------------------
/src-cpp/adt/pdeq.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief double ended queue of generic pointers.
23 | * @author Christian von Roques
24 | * @version $Id: pdeq.h 26440 2009-08-28 09:26:27Z matze $
25 | */
26 | #ifndef FIRM_ADT_PDEQ_H
27 | #define FIRM_ADT_PDEQ_H
28 |
29 | /**
30 | * The type of the pointer compare function.
31 | *
32 | * @param elem The list element.
33 | * @param key The user supplied key.
34 | *
35 | * @return 0 if the element matches the key, non-zero else.
36 | */
37 | typedef int (*cmp_fun)(const void *elem, const void *key);
38 |
39 | /**
40 | * The pointer double ended queue (list).
41 | */
42 | typedef struct pdeq pdeq;
43 |
44 | /**
45 | * Creates a new double ended pointer list.
46 | *
47 | * @return A new list.
48 | */
49 | pdeq *new_pdeq(void);
50 |
51 | /**
52 | * Creates a new double ended pointer list and puts an initial pointer element in.
53 | *
54 | * @param x The pointer element to put in.
55 | *
56 | * @return The new list.
57 | */
58 | pdeq *new_pdeq1(const void *x);
59 |
60 | /**
61 | * Delete a double ended pointer list.
62 | *
63 | * @param dq The list to be deleted.
64 | */
65 | void del_pdeq(pdeq *dq);
66 |
67 | /**
68 | * Returns the lenght of a double ended pointer list.
69 | *
70 | * @param dq The list.
71 | */
72 | int pdeq_len(pdeq *dq);
73 |
74 | /**
75 | * Checks if a list is empty.
76 | *
77 | * @param dq The list.
78 | *
79 | * @return non-zero if the list is empty.
80 | */
81 | int pdeq_empty(pdeq *dq);
82 |
83 | /**
84 | * Returns non-zero if a double ended pointer list
85 | * contains a pointer x.
86 | *
87 | * @param dq The list.
88 | * @param x The pointer to be searched for.
89 | */
90 | int pdeq_contains(pdeq *dq, const void *x);
91 |
92 | /**
93 | * Search a key in a double ended pointer list, the search
94 | * is controlled by a compare function.
95 | * An element is found, if the compare function returns 0.
96 | * The search is started from the left site of the list.
97 | *
98 | * @param qp The list.
99 | * @param cmp The compare function.
100 | * @param key The search key.
101 | *
102 | * @return The address of the element entry if the key was found,
103 | * NULL else.
104 | */
105 | void *pdeq_search(pdeq *qp, cmp_fun cmp, const void *key);
106 |
107 | /**
108 | * Convert the double ended pointer list into a linear array beginning from
109 | * left, the first element in the linear array will be the left one.
110 | *
111 | * @param qp The list.
112 | * @param dst A pointer to a pointer array with must be at least
113 | * pdeq_len(dq) * sizeof(void *)
114 | *
115 | * @return dst
116 | */
117 | void **pdeq_copyl(pdeq *qp, const void **dst);
118 |
119 | /**
120 | * Convert the double ended pointer list into a linear array beginning from
121 | * right, the first element in the linear array will be the right one.
122 | *
123 | * @param qp The list.
124 | * @param dst A pointer to a pointer array with must be at least
125 | * pdeq_len(dq) * sizeof(void *)
126 | *
127 | * @return dst
128 | */
129 | void **pdeq_copyr(pdeq *qp, const void **dst);
130 |
131 | /**
132 | * Add a pointer to the left side of a double ended pointer list.
133 | *
134 | * @param dq The list to add a pointer to.
135 | * @param x The pointer element to be added
136 | *
137 | * @return The list.
138 | */
139 | pdeq *pdeq_putl(pdeq *dq, const void *x);
140 |
141 | /**
142 | * Add a pointer to the right side of a double ended pointer list.
143 | *
144 | * @param dq The list to add a pointer to.
145 | * @param x The pointer element to be added
146 | *
147 | * @return The list.
148 | */
149 | pdeq *pdeq_putr(pdeq *dq, const void *x);
150 |
151 | /**
152 | * Retrieve (and remove) a pointer from the left site of a double ended pointer
153 | * list.
154 | *
155 | * @param dq The list
156 | * @return The pointer element.
157 | * @remark This function will fail if the list is empty.
158 | */
159 | void *pdeq_getl(pdeq *dq);
160 |
161 | /**
162 | * Retrieve (and remove) a pointer from the right site of a double ended pointer
163 | * list.
164 | *
165 | * @param dq The list
166 | * @return The pointer element.
167 | * @remark This function will fail if the list is empty.
168 | */
169 | void *pdeq_getr(pdeq *dq);
170 |
171 | #ifdef NDEBUG
172 | #define PDEQ_VRFY(deq) ((void)0)
173 | #else
174 | #define PDEQ_VRFY(deq) _pdeq_vrfy ((deq))
175 | void _pdeq_vrfy(pdeq *dq);
176 | #endif
177 |
178 | /**
179 | * The pdeq is often used as a wait queue. A helper
180 | * type to support this.
181 | */
182 | typedef pdeq waitq;
183 |
184 | /**
185 | * Creates a new pointer wait queue (fifo).
186 | *
187 | * @return A new queue.
188 | */
189 | #define new_waitq() new_pdeq()
190 |
191 | /**
192 | * Delete a wait queue (fifo)
193 | *
194 | * @param wq The wait queue.
195 | */
196 | #define del_waitq(wq) del_pdeq(wq)
197 |
198 | /**
199 | * Retrieve a pointer from the wait queue (fifo).
200 | *
201 | * @param wq The wait queue.
202 | *
203 | * @return The pointer element.
204 | *
205 | * @remark This function will fail if the queue is empty.
206 | */
207 | #define waitq_get(wq) pdeq_getl(wq)
208 |
209 | /**
210 | * Add a pointer to the wait queue (fifo).
211 | *
212 | * @param wq The wait queue
213 | * @param x The pointer element to be added
214 | *
215 | * @return The wait queue.
216 | */
217 | #define waitq_put(wq, x) pdeq_putr((wq), (x))
218 |
219 | /**
220 | * Checks if a wait queue is empty.
221 | *
222 | * @param wq The wait queue.
223 | *
224 | * @return non-zero if the queue is empty.
225 | */
226 | #define waitq_empty(wq) pdeq_empty(wq)
227 |
228 | /**
229 | * The pdeq can be used as a stack. A helper
230 | * type to support this.
231 | */
232 | typedef pdeq stack;
233 |
234 | /**
235 | * Creates a new pointer stack (lifo).
236 | *
237 | * @return A new stack.
238 | */
239 | #define new_stack() new_pdeq()
240 |
241 | /**
242 | * Pop a pointer from the stack (lifo).
243 | *
244 | * @param st The stack.
245 | *
246 | * @return The pointer element.
247 | *
248 | * @remark This function will fail if the stack is empty.
249 | */
250 | #define stack_pop(st) pdeq_getr(st)
251 |
252 | /**
253 | * Push a pointer to the stack (lifo).
254 | *
255 | * @param st The stack.
256 | * @param x The pointer element to be added
257 | *
258 | * @return The stack.
259 | */
260 | #define stack_push(st, x) pdeq_putr((st), (x))
261 |
262 | /**
263 | * Checks if a stack is empty.
264 | *
265 | * @param st The stack.
266 | *
267 | * @return non-zero if the stack is empty.
268 | */
269 | #define stack_empty(st) pdeq_empty(wq)
270 |
271 | #endif
272 |
--------------------------------------------------------------------------------
/src-cpp/adt/pdeq.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libfirm/liboo/e4c221831da8fb29780cb17f0d4af0d83e05621f/src-cpp/adt/pdeq.o
--------------------------------------------------------------------------------
/src-cpp/adt/raw_bitset.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief helper functions for working with raw bitsets
23 | * @date 15.10.2004
24 | * @author Matthias Braun
25 | * @version $Id: raw_bitset.h 27155 2010-02-14 14:38:55Z mallon $
26 | * @brief
27 | * Raw bitsets are constructed from unsigned int arrays. Additional information
28 | * like the size of the bitset or the used memory are not stored for
29 | * efficiency reasons.
30 | *
31 | * These bitsets need less space than bitset_t and their representation
32 | * as int arrays allows having constant bitsets in the ro data segment.
33 | * They should for smaller bitset, whose length is known through other means
34 | * (a typical usage case is a set of cpu registers)
35 | *
36 | * The bitset is built as an array of unsigned integers. It is assumed that
37 | * exactly 32 bits may be put into each element of the array. If there are
38 | * remaining bits, then they should be 0
39 | */
40 | #ifndef FIRM_ADT_RAW_BITSET_H
41 | #define FIRM_ADT_RAW_BITSET_H
42 |
43 | #include
44 | #include "obst.h"
45 |
46 | /** The base type for raw bitsets. */
47 | typedef unsigned int rawbs_base_t;
48 |
49 | #define BITS_PER_ELEM (sizeof(rawbs_base_t) * 8)
50 | #define BITSET_SIZE_ELEMS(size_bits) ((size_bits)/BITS_PER_ELEM + 1)
51 | #define BITSET_SIZE_BYTES(size_bits) (BITSET_SIZE_ELEMS(size_bits) * sizeof(rawbs_base_t))
52 | #define BITSET_ELEM(bitset,pos) bitset[pos / BITS_PER_ELEM]
53 |
54 | /**
55 | * Allocate an empty raw bitset on the heap.
56 | *
57 | * @param size number of bits in the bitset
58 | *
59 | * @return the new bitset
60 | */
61 | static inline unsigned *rbitset_malloc(unsigned size) {
62 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
63 | unsigned *res = xmalloc(size_bytes);
64 | memset(res, 0, size_bytes);
65 |
66 | return res;
67 | }
68 |
69 | /**
70 | * Allocate an empty raw bitset on the stack.
71 | *
72 | * @param res will contain the newly allocated bitset
73 | * @param size number of bits in the bitset
74 | */
75 | #define rbitset_alloca(res, size) \
76 | do { \
77 | unsigned size_bytes = BITSET_SIZE_BYTES(size); \
78 | res = alloca(size_bytes); \
79 | memset(res, 0, size_bytes); \
80 | } while(0)
81 |
82 | /**
83 | * Allocate an empty raw bitset on an obstack.
84 | *
85 | * @param obst the obstack where the bitset is allocated on
86 | * @param size number of bits in the bitset
87 | *
88 | * @return the new bitset
89 | */
90 | static inline unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size)
91 | {
92 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
93 | unsigned *res = obstack_alloc(obst, size_bytes);
94 | memset(res, 0, size_bytes);
95 |
96 | return res;
97 | }
98 |
99 | /**
100 | * Allocate an empty raw bitset including the size on an obstack.
101 | * The size of this bitset can be accessed by bitset[-1].
102 | *
103 | * @param obst the obstack where the bitset is allocated on
104 | * @param size number of bits in the bitset
105 | *
106 | * @return the new bitset
107 | */
108 | static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size)
109 | {
110 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
111 | unsigned *res = obstack_alloc(obst, size_bytes + sizeof(unsigned));
112 | *res = size;
113 | ++res;
114 | memset(res, 0, size_bytes);
115 |
116 | return res;
117 | }
118 |
119 | /** Return the size of a bitset allocated with a *_w_size_* function */
120 | #define rbitset_size(set) (set)[-1]
121 |
122 | /**
123 | * Duplicate a raw bitset on an obstack.
124 | *
125 | * @param obst the obstack where the bitset is allocated on
126 | * @param old_bitset the bitset to be duplicated
127 | * @param size number of bits in the bitset
128 | *
129 | * @return the new bitset
130 | */
131 | static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
132 | const unsigned *old_bitset, unsigned size)
133 | {
134 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
135 | unsigned *res = obstack_alloc(obst, size_bytes);
136 | memcpy(res, old_bitset, size_bytes);
137 |
138 | return res;
139 | }
140 |
141 | /**
142 | * Check if a bitset is empty, ie all bits cleared.
143 | */
144 | static inline int rbitset_is_empty(unsigned *bitset, unsigned size)
145 | {
146 | unsigned n = BITSET_SIZE_ELEMS(size);
147 | unsigned i;
148 | for (i = 0; i < n; ++i) {
149 | if (bitset[i] != 0)
150 | return 0;
151 | }
152 |
153 | return 1;
154 | }
155 |
156 | /**
157 | * Set a bit at position pos.
158 | *
159 | * @param bitset the bitset
160 | * @param pos the position of the bit to be set
161 | */
162 | static inline void rbitset_set(unsigned *bitset, unsigned pos)
163 | {
164 | BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
165 | }
166 |
167 | /**
168 | * Set all bits in a given bitset.
169 | *
170 | * @param bitset the bitset
171 | * @param size number of bits in the bitset
172 | */
173 | static inline void rbitset_set_all(unsigned *bitset, unsigned size)
174 | {
175 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
176 | memset(bitset, ~0, size_bytes);
177 | }
178 |
179 |
180 | /**
181 | * Clear a bit at position pos.
182 | *
183 | * @param bitset the bitset
184 | * @param pos the position of the bit to be clear
185 | */
186 | static inline void rbitset_clear(unsigned *bitset, unsigned pos)
187 | {
188 | BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM));
189 | }
190 |
191 | /**
192 | * Clear all bits in a given bitset.
193 | *
194 | * @param bitset the bitset
195 | * @param size number of bits in the bitset
196 | */
197 | static inline void rbitset_clear_all(unsigned *bitset, unsigned size)
198 | {
199 | unsigned size_bytes = BITSET_SIZE_BYTES(size);
200 | memset(bitset, 0, size_bytes);
201 | }
202 |
203 | /**
204 | * Check if a bit is set at position pos.
205 | *
206 | * @param bitset the bitset
207 | * @param pos the position of the bit to check
208 | */
209 | static inline int rbitset_is_set(const unsigned *bitset, unsigned pos)
210 | {
211 | return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
212 | }
213 |
214 | /**
215 | * Inplace Intersection of two sets.
216 | *
217 | * @param dst the destination bitset and first operand
218 | * @param src the second bitset
219 | * @param size size of both bitsets
220 | */
221 | static inline void rbitset_and(unsigned *dst, const unsigned *src, unsigned size)
222 | {
223 | unsigned i, n = BITSET_SIZE_ELEMS(size);
224 |
225 | for (i = 0; i < n; ++i) {
226 | dst[i] &= src[i];
227 | }
228 | }
229 |
230 | /**
231 | * Inplace Union of two sets.
232 | *
233 | * @param dst the destination bitset and first operand
234 | * @param src the second bitset
235 | * @param size size of both bitsets
236 | */
237 | static inline void rbitset_or(unsigned *dst, const unsigned *src, unsigned size)
238 | {
239 | unsigned i, n = BITSET_SIZE_ELEMS(size);
240 |
241 | for (i = 0; i < n; ++i) {
242 | dst[i] |= src[i];
243 | }
244 | }
245 |
246 | /**
247 | * Remove all bits in src from dst.
248 | *
249 | * @param dst the destination bitset and first operand
250 | * @param src the second bitset
251 | * @param size size of both bitsets
252 | */
253 | static inline void rbitset_andnot(unsigned *dst, const unsigned *src, unsigned size)
254 | {
255 | unsigned i, n = BITSET_SIZE_ELEMS(size);
256 |
257 | for (i = 0; i < n; ++i) {
258 | dst[i] &= ~src[i];
259 | }
260 | }
261 |
262 | /**
263 | * Xor of two bitsets.
264 | *
265 | * @param dst the destination bitset and first operand
266 | * @param src the second bitset
267 | * @param size size of both bitsets
268 | */
269 | static inline void rbitset_xor(unsigned *dst, const unsigned *src, unsigned size)
270 | {
271 | unsigned i, n = BITSET_SIZE_ELEMS(size);
272 |
273 | for (i = 0; i < n; ++i) {
274 | dst[i] ^= src[i];
275 | }
276 | }
277 |
278 | /**
279 | * Returns 1 of two bitsets are equal.
280 | *
281 | * @param bitset1 the first bitset
282 | * @param bitset2 the second bitset
283 | * @param size size of both bitsets
284 | */
285 | static inline int rbitset_equal(const unsigned *bitset1,
286 | const unsigned *bitset2, size_t size)
287 | {
288 | return memcmp(bitset1, bitset2, BITSET_SIZE_BYTES(size)) == 0;
289 | }
290 |
291 | /**
292 | * Tests wether 2 bitsets wether at least 1 bit is set in both.
293 | *
294 | * @param bitset1 the first bitset
295 | * @param bitset2 the second bitset
296 | * @param size size of both bitsets
297 | */
298 | static inline int rbitsets_have_common(const unsigned *bitset1,
299 | const unsigned *bitset2, size_t size)
300 | {
301 | unsigned i;
302 | unsigned n = BITSET_SIZE_ELEMS(size);
303 |
304 | for (i = 0; i < n; ++i) {
305 | if ((bitset1[i] & bitset2[i]) != 0)
306 | return 1;
307 | }
308 | return 0;
309 | }
310 |
311 | /**
312 | * Copy a raw bitset into another.
313 | *
314 | * @param dst the destination set
315 | * @param src the source set
316 | * @param size size of both bitsets
317 | */
318 | static inline void rbitset_copy(unsigned *dst, const unsigned *src, size_t size)
319 | {
320 | memcpy(dst, src, BITSET_SIZE_BYTES(size));
321 | }
322 |
323 | #endif
324 |
--------------------------------------------------------------------------------
/src-cpp/adt/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of libFirm.
3 | * Copyright (C) 2012 University of Karlsruhe.
4 | */
5 |
6 | /**
7 | * @file
8 | * @date 31.05.2005
9 | * @author Sebastian Hack
10 | * @brief Miscellaneous utility macros.
11 | */
12 | #ifndef FIRM_ADT_UTIL_H
13 | #define FIRM_ADT_UTIL_H
14 |
15 | #include
16 |
17 | /**
18 | * Make pointer to the struct from a pointer to a member of that struct.
19 | * @param ptr The pointer to the member.
20 | * @param type The type of the struct.
21 | * @param member The name of the member.
22 | * @return A pointer to the struct member is in.
23 | */
24 | #define firm_container_of(ptr, type, member) \
25 | ((type *) ((char *) (ptr) - offsetof(type, member)))
26 |
27 | /**
28 | * Returns size of a static array. Warning: This returns invalid values for
29 | * dynamically allocated arrays.
30 | *
31 | * @param a static array
32 | */
33 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
34 |
35 | #undef MIN
36 | #undef MAX
37 | #define MAX(x, y) ((x) > (y) ? (x) : (y))
38 | #define MIN(x, y) ((x) < (y) ? (x) : (y))
39 |
40 | /**
41 | * Three valued compare as demanded by e.g. qsort(3)
42 | * @param c A number.
43 | * @param d Another number.
44 | * @return 0 if c == d, -1 if c < d, 1 if c > d.
45 | */
46 | #define QSORT_CMP(c, d) (((c) > (d)) - ((c) < (d)))
47 |
48 | /**
49 | * convert an integer into pointer
50 | */
51 | #define INT_TO_PTR(v) ((void *)((char *)0 + (v)))
52 |
53 | /**
54 | * convert a pointer into an integer
55 | */
56 | #define PTR_TO_INT(v) (((char *)(v) - (char *)0))
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/src-cpp/adt/xmalloc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
3 | *
4 | * This file is part of libFirm.
5 | *
6 | * This file may be distributed and/or modified under the terms of the
7 | * GNU General Public License version 2 as published by the Free Software
8 | * Foundation and appearing in the file LICENSE.GPL included in the
9 | * packaging of this file.
10 | *
11 | * Licensees holding valid libFirm Professional Edition licenses may use
12 | * this file in accordance with the libFirm Commercial License.
13 | * Agreement provided with the Software.
14 | *
15 | * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 | * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 | * PURPOSE.
18 | */
19 |
20 | /**
21 | * @file
22 | * @brief never failing wrappers for malloc() & friends.
23 | * @author Markus Armbruster
24 | * @version $Id: xmalloc.h 26728 2009-11-19 13:21:05Z matze $
25 | * @note The functions here never fail because they simply abort your
26 | * program in case of an error.
27 | */
28 | #ifndef FIRM_ADT_XMALLOC_H
29 | #define FIRM_ADT_XMALLOC_H
30 |
31 | #ifdef __cplusplus
32 | extern "C" {
33 | #endif
34 |
35 | #include
36 | #include
37 | #include
38 |
39 | /* xmalloc() & friends. */
40 |
41 | void *xmalloc(size_t size);
42 | void *xrealloc(void *ptr, size_t size);
43 | char *xstrdup(const char *str);
44 |
45 | #define xfree(ptr) free(ptr)
46 |
47 | /**
48 | * Allocate n objects of a certain type
49 | */
50 | #define XMALLOCN(type, n) ((type*)xmalloc(sizeof(type) * (n)))
51 |
52 | /**
53 | * Allocate n objects of a certain type and zero them
54 | */
55 | #define XMALLOCNZ(type, n) ((type*)memset(xmalloc(sizeof(type) * (n)), 0, sizeof(type) * (n)))
56 |
57 | /**
58 | * Allocate one object of a certain type
59 | */
60 | #define XMALLOC(type) XMALLOCN(type, 1)
61 |
62 | /**
63 | * Allocate one object of a certain type and zero it
64 | */
65 | #define XMALLOCZ(type) XMALLOCNZ(type, 1)
66 |
67 | /**
68 | * Reallocate n objects of a certain type
69 | */
70 | #define XREALLOC(ptr, type, n) ((type*)xrealloc(ptr, sizeof(type) * (n)))
71 |
72 | /**
73 | * Allocate an object with n elements of a flexible array member
74 | */
75 | #define XMALLOCF(type, member, n) ((type*)xmalloc(offsetof(type, member) + sizeof(*((type*)0)->member) * (n)))
76 |
77 | /**
78 | * Allocate an object with n elements of a flexible array member and zero the
79 | * whole object
80 | */
81 | #define XMALLOCFZ(type, member, n) ((type*)memset(XMALLOCF(type, member, (n)), 0, offsetof(type, member) + sizeof(*((type*)0)->member) * (n)))
82 |
83 | /**
84 | * Allocate n objects of a certain type on the stack
85 | */
86 | #define ALLOCAN(type, n) ((type*)alloca(sizeof(type) * (n)))
87 |
88 | /**
89 | * Allocate n objects of a certain type on the stack and zero them
90 | */
91 | #define ALLOCANZ(type, n) ((type*)memset((type*)alloca(sizeof(type) * (n)), 0, sizeof(type) * (n)))
92 |
93 | /**
94 | * Allocate n objects of a certain type on the given obstack
95 | */
96 | #define OALLOCN(obst, type, n) ((type*)obstack_alloc((obst), sizeof(type) * (n)))
97 |
98 | /**
99 | * Allocate n objects of a certain type on the given obstack and zero them
100 | */
101 | #define OALLOCNZ(obst, type, n) ((type*)memset(OALLOCN((obst), type, (n)), 0, sizeof(type) * (n)))
102 |
103 | /**
104 | * Allocate one object of a certain type on the given obstack
105 | */
106 | #define OALLOC(obst, type) OALLOCN(obst, type, 1)
107 |
108 | /**
109 | * Allocate one object of a certain type on the given obstack and zero it
110 | */
111 | #define OALLOCZ(obst, type) OALLOCNZ(obst, type, 1)
112 |
113 | /**
114 | * Allocate an object with n elements of a flexible array member on the given
115 | * obstck
116 | */
117 | #define OALLOCF(obst, type, member, n) ((type*)obstack_alloc((obst), offsetof(type, member) + sizeof(*((type*)0)->member) * (n)))
118 |
119 | /**
120 | * Allocate an object with n elements of a flexible array member on the given
121 | * obstack and zero the whole object
122 | */
123 | #define OALLOCFZ(obst, type, member, n) ((type*)memset(OALLOCF((obst), type, member, (n)), 0, offsetof(type, member) + sizeof(*((type*)0)->member) * (n)))
124 |
125 |
126 | /* Includes for alloca() */
127 | #ifdef _WIN32
128 | #include
129 | #endif
130 | #ifdef HAVE_ALLOCA_H
131 | #include
132 | #endif
133 |
134 | #ifdef __cplusplus
135 | }
136 | #endif
137 |
138 | #endif
139 |
--------------------------------------------------------------------------------
/src-cpp/debuginfo.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include "liboo/debuginfo.h"
6 | #include "adt/obst.h"
7 | #include "adt/error.h"
8 | #include "adt/xmalloc.h"
9 |
10 | typedef struct debuginfo_t {
11 | ident *filename;
12 | uint32_t line;
13 | uint16_t column;
14 | uint16_t length;
15 | } debuginfo_t;
16 |
17 | static struct obstack obst;
18 |
19 | static src_loc_t dbg_retrieve(const dbg_info *dbg)
20 | {
21 | const debuginfo_t *info = (const debuginfo_t*) dbg;
22 | src_loc_t loc = { NULL, 0, 0 };
23 | if (info == NULL)
24 | return loc;
25 | loc.file = get_id_str(info->filename);
26 | loc.line = info->line;
27 | loc.column = info->column;
28 | return loc;
29 | }
30 |
31 | void debuginfo_init(void)
32 | {
33 | obstack_init(&obst);
34 | ir_set_debug_retrieve(dbg_retrieve);
35 | }
36 |
37 | void debuginfo_deinit(void)
38 | {
39 | obstack_free(&obst, NULL);
40 | }
41 |
42 | const dbg_info *create_debuginfo(ident *filename, unsigned line,
43 | unsigned column, unsigned length)
44 | {
45 | debuginfo_t *info = OALLOC(&obst, debuginfo_t);
46 | info->filename = filename;
47 | info->line = (uint32_t) line;
48 | info->column = (uint16_t) column;
49 | info->length = (uint16_t) length;
50 | return (const dbg_info*) info;
51 | }
52 |
--------------------------------------------------------------------------------
/src-cpp/dmemory.c:
--------------------------------------------------------------------------------
1 | #include "liboo/dmemory.h"
2 | #include "liboo/nodes.h"
3 |
4 | #include
5 | #include "liboo/ddispatch.h"
6 | #include "liboo/oo.h"
7 | #include "adt/error.h"
8 | #include "adt/util.h"
9 |
10 | struct dmemory_model_t {
11 | get_arraylength_t get_arraylength;
12 | } dmemory_model;
13 |
14 | static ir_mode *default_arraylength_mode;
15 |
16 | ir_node *dmemory_default_get_arraylength(dbg_info *dbgi, ir_node *block,
17 | ir_node *objptr, ir_node **mem)
18 | {
19 | /* calculate address of arraylength field */
20 | ir_graph *irg = get_irn_irg(block);
21 | int length_len = get_mode_size_bytes(default_arraylength_mode);
22 | ir_node *cnst = new_r_Const_long(irg, mode_P, -length_len);
23 | ir_node *length_addr = new_rd_Add(dbgi, block, objptr, cnst);
24 |
25 | ir_node *cur_mem = *mem;
26 | ir_type *length_type = get_type_for_mode(default_arraylength_mode);
27 | ir_node *load = new_rd_Load(dbgi, block, cur_mem, length_addr, default_arraylength_mode, length_type, cons_none);
28 | cur_mem = new_r_Proj(load, mode_M, pn_Load_M);
29 | ir_node *len = new_r_Proj(load, default_arraylength_mode, pn_Load_res);
30 | *mem = cur_mem;
31 | return len;
32 | }
33 |
34 | void dmemory_init(void)
35 | {
36 | default_arraylength_mode = mode_Is;
37 | dmemory_model.get_arraylength = dmemory_default_get_arraylength;
38 | }
39 |
40 | void dmemory_lower_Arraylength(ir_node *arraylength)
41 | {
42 | dbg_info *dbgi = get_irn_dbg_info(arraylength);
43 | ir_node *array_ref = get_Arraylength_ptr(arraylength);
44 | ir_node *block = get_nodes_block(arraylength);
45 | ir_node *cur_mem = get_Arraylength_mem(arraylength);
46 | ir_node *len = (*dmemory_model.get_arraylength)(dbgi, block, array_ref, &cur_mem);
47 |
48 | ir_node *in[pn_Arraylength_max+1] = {
49 | [pn_Arraylength_M] = cur_mem,
50 | [pn_Arraylength_res] = len
51 | };
52 | turn_into_tuple(arraylength, ARRAY_SIZE(in), in);
53 | }
54 |
55 | void dmemory_set_allocation_methods(get_arraylength_t ga_func)
56 | {
57 | assert(ga_func);
58 | dmemory_model.get_arraylength = ga_func;
59 | }
60 |
--------------------------------------------------------------------------------
/src-cpp/eh.c:
--------------------------------------------------------------------------------
1 | #include "liboo/eh.h"
2 | #include "liboo/nodes.h"
3 | #include "adt/error.h"
4 | #include "adt/obst.h"
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #ifdef LIBOO_EXCEPTION_SUPPORT
11 |
12 | struct _lpad_t;
13 | typedef struct _lpad_t lpad_t;
14 | struct _lpad_t {
15 | ir_node *handler_header_block;
16 | ir_node *cur_block;
17 | ir_node *exception_object;
18 | bool used;
19 | lpad_t *prev;
20 | };
21 |
22 | static struct obstack lpads;
23 | static lpad_t *top;
24 |
25 | static ir_entity *exception_object_entity;
26 | static ir_entity *throw_entity;
27 |
28 | ir_node *eh_get_exception_object(void)
29 | {
30 | ir_node *cur_mem = get_store();
31 |
32 | ir_node *ex_symc = new_Address(exception_object_entity);
33 | ir_node *ex_load = new_Load(cur_mem, ex_symc, mode_P, cons_none);
34 | cur_mem = new_Proj(ex_load, mode_M, pn_Load_M);
35 | ir_node *ex_obj = new_Proj(ex_load, mode_P, pn_Load_res);
36 |
37 | set_store(cur_mem);
38 | return ex_obj;
39 | }
40 |
41 | static void store_exception_object(ir_node *exo_ptr)
42 | {
43 | ir_node *cur_mem = get_store();
44 |
45 | ir_node *ex_symc = new_Address(exception_object_entity);
46 | ir_node *ex_store = new_Store(cur_mem, ex_symc, exo_ptr, cons_none);
47 | cur_mem = new_Proj(ex_store, mode_M, pn_Store_M);
48 |
49 | set_store(cur_mem);
50 | }
51 |
52 | void eh_init(void)
53 | {
54 | obstack_init(&lpads);
55 | ir_type *type_reference = new_type_primitive(mode_P);
56 | exception_object_entity = new_entity(get_tls_type(), new_id_from_str("__oo_rt_exception_object__"), type_reference);
57 | set_entity_initializer(exception_object_entity, get_initializer_null());
58 |
59 | ir_type *throw_type = new_type_method(1, 0);
60 | set_method_param_type(throw_type, 0, type_reference);
61 | throw_entity = new_entity(get_glob_type(), new_id_from_str("firm_personality"), throw_type);
62 | set_entity_visibility(throw_entity, ir_visibility_external);
63 |
64 | top = NULL;
65 | }
66 |
67 | void eh_deinit(void)
68 | {
69 | obstack_free(&lpads, NULL);
70 | }
71 |
72 | void eh_start_method(void)
73 | {
74 | assert (irg_is_constrained(get_current_ir_graph(), IR_GRAPH_CONSTRAINT_CONSTRUCTION));
75 | assert (obstack_object_size(&lpads) == 0);
76 | eh_new_lpad();
77 | }
78 |
79 | void eh_new_lpad(void)
80 | {
81 | lpad_t *new_pad = (lpad_t*) obstack_alloc(&lpads, sizeof(lpad_t));
82 | new_pad->handler_header_block = new_immBlock();
83 | new_pad->cur_block = new_pad->handler_header_block;
84 | new_pad->exception_object = NULL;
85 | new_pad->used = false;
86 | new_pad->prev = top;
87 |
88 | top = new_pad;
89 |
90 | ir_node *saved_block = get_cur_block();
91 | set_cur_block(new_pad->cur_block);
92 |
93 | top->exception_object = eh_get_exception_object();
94 |
95 | set_cur_block(saved_block);
96 | }
97 |
98 | void eh_add_handler(ir_type *catch_type, ir_node *catch_block)
99 | {
100 | assert (top->prev); //e.g., not the default handler
101 | assert (top->cur_block && "Cannot add handler after an catch all was registered");
102 |
103 | ir_node *saved_block = get_cur_block();
104 | set_cur_block(top->cur_block);
105 |
106 | if (catch_type) {
107 | ir_node *cur_mem = get_store();
108 | ir_node *instanceof = new_InstanceOf(cur_mem, top->exception_object, catch_type);
109 | cur_mem = new_Proj(instanceof, mode_M, pn_InstanceOf_M);
110 | ir_node *result = new_Proj(instanceof, mode_b, pn_InstanceOf_res);
111 | ir_node *cond = new_Cond(result);
112 |
113 | ir_node *proj_match = new_Proj(cond, mode_X, pn_Cond_true);
114 | add_immBlock_pred(catch_block, proj_match);
115 | // will be matured elsewhere
116 |
117 | ir_node *proj_go_on = new_Proj(cond, mode_X, pn_Cond_false);
118 | ir_node *new_block = new_immBlock();
119 | add_immBlock_pred(new_block, proj_go_on);
120 | mature_immBlock(new_block);
121 | top->cur_block = new_block;
122 | set_store(cur_mem);
123 | } else {
124 | ir_node *jmp = new_Jmp();
125 | add_immBlock_pred(catch_block, jmp);
126 | top->cur_block = NULL;
127 | }
128 |
129 | set_cur_block(saved_block);
130 | }
131 |
132 | ir_node *eh_new_Call(ir_node * irn_ptr, int arity, ir_node *const * in, ir_type* type)
133 | {
134 | ir_node *jmp = new_Jmp();
135 | ir_node *call_block = new_immBlock();
136 | add_immBlock_pred(call_block, jmp);
137 | mature_immBlock(call_block);
138 | set_cur_block(call_block);
139 |
140 | ir_node *cur_mem = get_store();
141 | ir_node *call = new_Call(cur_mem, irn_ptr, arity, in, type);
142 | ir_set_throws_exception(call, 1);
143 | ir_node *proj_except = new_Proj(call, mode_X, pn_Call_X_except);
144 | cur_mem = new_Proj(call, mode_M, pn_Call_M);
145 | set_store(cur_mem);
146 |
147 | add_immBlock_pred(top->handler_header_block, proj_except);
148 |
149 | ir_node *proj_regular = new_Proj(call, mode_X, pn_Call_X_regular);
150 | ir_node *new_block = new_immBlock();
151 | add_immBlock_pred(new_block, proj_regular);
152 | mature_immBlock(new_block);
153 | set_cur_block(new_block);
154 |
155 | top->used = true;
156 |
157 | return call;
158 | }
159 |
160 | void eh_throw(ir_node *exo_ptr)
161 | {
162 | store_exception_object(exo_ptr);
163 |
164 | ir_node *throw = new_Jmp();
165 |
166 | add_immBlock_pred(top->handler_header_block, throw);
167 | top->used = true;
168 | set_cur_block(NULL);
169 | }
170 |
171 | void eh_pop_lpad(void)
172 | {
173 | mature_immBlock(top->handler_header_block);
174 |
175 | //assert (top->used && "No exception is ever thrown");
176 |
177 | lpad_t *prev = top->prev;
178 | assert (prev);
179 |
180 | if (top->cur_block) {
181 | // the popped lpad didn't have a catch all handler and therefore is still "open".
182 | ir_node *saved_block = get_cur_block();
183 | set_cur_block(top->cur_block);
184 |
185 | ir_node *jmp = new_Jmp();
186 | add_immBlock_pred(prev->handler_header_block, jmp);
187 |
188 | set_cur_block(saved_block);
189 | }
190 |
191 | obstack_free(&lpads, top);
192 | top = prev;
193 | }
194 |
195 | void eh_end_method(void)
196 | {
197 | assert (! top->prev); // the explicit stuff is gone, we have the default handler
198 |
199 | if (top->used) {
200 | mature_immBlock(top->handler_header_block);
201 |
202 | assert (top->cur_block); // would fail if front end adds an catch all handler to the default handler
203 |
204 | ir_node *saved_block = get_cur_block();
205 | set_cur_block(top->cur_block);
206 | ir_node *cur_mem = get_store();
207 | ir_node *raise = new_Raise(cur_mem, top->exception_object);
208 | ir_node *proj = new_Proj(raise, mode_X, pn_Raise_X);
209 | cur_mem = new_Proj(raise, mode_M, pn_Raise_M);
210 | set_store(cur_mem);
211 |
212 | ir_node *end_block = get_irg_end_block(get_current_ir_graph());
213 | add_immBlock_pred(end_block, proj);
214 |
215 | set_cur_block(saved_block);
216 | }
217 |
218 | obstack_free(&lpads, top);
219 | top = NULL;
220 | }
221 |
222 | void eh_lower_Raise(ir_node *raise, ir_node *proj)
223 | {
224 | assert (is_Raise(raise) && is_Proj(proj));
225 |
226 | ir_node *ex_obj = get_Raise_exo_ptr(raise);
227 | ir_node *block = get_nodes_block(raise);
228 | ir_graph *irg = get_irn_irg(raise);
229 | ir_node *cur_mem = get_Raise_mem(raise);
230 |
231 | ir_node *c_symc = new_r_SymConst(irg, throw_entity);
232 | ir_node *in[1] = { ex_obj };
233 |
234 | ir_node *throw = new_r_Call(block, cur_mem, c_symc, 1, in, get_entity_type(throw_entity));
235 | ir_set_throws_exception(throw, 1);
236 | exchange(raise, throw);
237 | set_Proj_num(proj, pn_Call_X_except);
238 | }
239 |
240 | #else
241 |
242 | ir_node *eh_get_exception_object(void)
243 | {
244 | panic("liboo compiled without exception support");
245 | }
246 |
247 | void eh_init(void)
248 | {
249 | }
250 |
251 | void eh_deinit(void)
252 | {
253 | }
254 |
255 | void eh_start_method(void)
256 | {
257 | panic("liboo compiled without exception support");
258 | }
259 |
260 | void eh_new_lpad(void)
261 | {
262 | panic("liboo compiled without exception support");
263 | }
264 |
265 | void eh_add_handler(ir_type *catch_type, ir_node *catch_block)
266 | {
267 | (void)catch_type;
268 | (void)catch_block;
269 | panic("liboo compiled without exception support");
270 | }
271 |
272 | ir_node *eh_new_Call(ir_node * irn_ptr, int arity, ir_node *const * in, ir_type* type)
273 | {
274 | (void)irn_ptr;
275 | (void)arity;
276 | (void)in;
277 | (void)type;
278 | panic("liboo compiled without exception support");
279 | }
280 |
281 | void eh_throw(ir_node *exo_ptr)
282 | {
283 | (void)exo_ptr;
284 | panic("liboo compiled without exception support");
285 | }
286 |
287 | void eh_pop_lpad(void)
288 | {
289 | panic("liboo compiled without exception support");
290 | }
291 |
292 | void eh_end_method(void)
293 | {
294 | panic("liboo compiled without exception support");
295 | }
296 |
297 | void eh_lower_Raise(ir_node *raise, ir_node *proj)
298 | {
299 | (void)raise;
300 | (void)proj;
301 | panic("liboo compiled without exception support");
302 | }
303 | #endif
304 |
--------------------------------------------------------------------------------
/src-cpp/nodes_attr.h:
--------------------------------------------------------------------------------
1 | #ifndef OO_NODES_ATTR_H
2 | #define OO_NODES_ATTR_H
3 |
4 | #include
5 |
6 | typedef struct op_InstanceOf_attr_t {
7 | ir_type *type;
8 | } op_InstanceOf_attr_t;
9 |
10 | typedef struct op_MethodSel_attr_t {
11 | ir_entity *entity;
12 | } op_MethodSel_attr_t;
13 |
14 | typedef struct op_VptrIsSet_attr_t {
15 | ir_type *type;
16 | } op_VptrIsSet_attr_t;
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src-cpp/oo.c:
--------------------------------------------------------------------------------
1 | #include "liboo/oo.h"
2 |
3 | #include
4 | #include "liboo/rtti.h"
5 | #include "liboo/dmemory.h"
6 | #include "liboo/nodes.h"
7 | #include "liboo/eh.h"
8 | #include "adt/obst.h"
9 | #include "libfirm/adt/pmap.h"
10 | #include "adt/error.h"
11 | #include "gen_irnode.h"
12 |
13 | typedef enum {
14 | oo_is_abstract = 1 << 0,
15 | oo_is_final = 1 << 1,
16 | oo_is_interface = 1 << 2,
17 | oo_is_inherited = 1 << 3,
18 | oo_is_extern = 1 << 4,
19 | oo_is_transient = 1 << 5
20 | } oo_info_flags;
21 |
22 | typedef enum {
23 | k_oo_BAD = k_ir_max+1,
24 | k_oo_type_info,
25 | k_oo_entity_info,
26 | k_oo_node_info,
27 | } oo_info_kind;
28 |
29 | typedef struct {
30 | oo_info_kind kind;
31 | unsigned uid;
32 | ir_entity *vptr;
33 | ir_entity *rtti;
34 | ir_entity *itt;
35 | ir_entity *vtable;
36 | unsigned vtable_size;
37 | unsigned flags;
38 | void *link;
39 | } oo_type_info;
40 |
41 | typedef struct {
42 | oo_info_kind kind;
43 | bool exclude_from_vtable;
44 | int vtable_index;
45 | unsigned flags;
46 | ddispatch_binding binding;
47 | void *link;
48 | } oo_entity_info;
49 |
50 | typedef struct {
51 | oo_info_kind kind;
52 | bool bind_statically;
53 | } oo_node_info;
54 |
55 | static struct obstack oo_info_obst;
56 | static pmap *oo_node_info_map = NULL;
57 |
58 | static ddispatch_interface_call interface_call_type;
59 |
60 | static oo_type_info *get_type_info(ir_type *type)
61 | {
62 | oo_type_info *ti = (oo_type_info*) get_type_link(type);
63 | if (ti == NULL) {
64 | ti = (oo_type_info*) obstack_alloc(&oo_info_obst, sizeof(oo_type_info));
65 | memset(ti, 0, sizeof(*ti));
66 | ti->kind = k_oo_type_info;
67 | set_type_link(type, ti);
68 | } else {
69 | assert(ti->kind == k_oo_type_info);
70 | }
71 | return ti;
72 | }
73 |
74 | static oo_entity_info *get_entity_info(ir_entity *entity)
75 | {
76 | oo_entity_info *ei = (oo_entity_info*) get_entity_link(entity);
77 | if (ei == NULL) {
78 | ei = (oo_entity_info*) obstack_alloc(&oo_info_obst, sizeof(oo_entity_info));
79 | memset(ei, 0, sizeof(*ei));
80 | ei->kind = k_oo_entity_info;
81 | ei->vtable_index = -1;
82 | set_entity_link(entity, ei);
83 | } else {
84 | assert(ei->kind == k_oo_entity_info);
85 | }
86 | return ei;
87 | }
88 |
89 | static oo_node_info *get_node_info(ir_node *node)
90 | {
91 | oo_node_info *ni = pmap_get(oo_node_info, oo_node_info_map, node);
92 | if (ni == NULL) {
93 | ni = (oo_node_info*) obstack_alloc(&oo_info_obst, sizeof(oo_node_info));
94 | memset(ni, 0, sizeof(*ni));
95 | ni->kind = k_oo_node_info;
96 | ni->bind_statically = false;
97 | pmap_insert(oo_node_info_map, node, ni);
98 | } else {
99 | assert(ni->kind == k_oo_node_info);
100 | }
101 | return ni;
102 | }
103 |
104 | unsigned oo_get_class_uid(ir_type *classtype)
105 | {
106 | assert(is_Class_type(classtype));
107 | oo_type_info *ti = get_type_info(classtype);
108 | return ti->uid;
109 | }
110 |
111 | void oo_set_class_uid(ir_type *classtype, unsigned uid)
112 | {
113 | assert(is_Class_type(classtype));
114 | oo_type_info *ti = get_type_info(classtype);
115 | ti->uid = uid;
116 | }
117 |
118 | ir_entity *oo_get_class_vtable_entity(ir_type *classtype)
119 | {
120 | assert(is_Class_type(classtype));
121 | oo_type_info *ti = get_type_info(classtype);
122 | return ti->vtable;
123 | }
124 |
125 | void oo_set_class_vtable_entity(ir_type *classtype, ir_entity *vtable)
126 | {
127 | assert(is_Class_type(classtype));
128 | oo_type_info *ti = get_type_info(classtype);
129 | ti->vtable = vtable;
130 | }
131 |
132 | unsigned oo_get_class_vtable_size(ir_type *classtype)
133 | {
134 | assert(is_Class_type(classtype));
135 | oo_type_info *ti = get_type_info(classtype);
136 |
137 | return ti->vtable_size;
138 | }
139 | void oo_set_class_vtable_size(ir_type *classtype, unsigned vtable_size)
140 | {
141 | assert(is_Class_type(classtype));
142 | oo_type_info *ti = get_type_info(classtype);
143 | ti->vtable_size = vtable_size;
144 | }
145 |
146 | ir_entity *oo_get_class_vptr_entity(ir_type *classtype)
147 | {
148 | assert(is_Class_type(classtype));
149 | oo_type_info *ti = get_type_info(classtype);
150 | if (ti->vptr != NULL)
151 | return ti->vptr;
152 |
153 | /* recursively search for vptr entity in supertypes */
154 | int n_supertypes = get_class_n_supertypes(classtype);
155 | for (int i = 0; i < n_supertypes; ++i) {
156 | ir_type *supertype = get_class_supertype(classtype, i);
157 | ti = get_type_info(supertype);
158 | if (ti->vptr != NULL)
159 | return ti->vptr;
160 | }
161 | return NULL;
162 | }
163 |
164 | void oo_set_class_vptr_entity(ir_type *classtype, ir_entity *vptr)
165 | {
166 | assert(is_Class_type(classtype));
167 | oo_type_info *ti = get_type_info(classtype);
168 | ti->vptr = vptr;
169 | }
170 |
171 | ir_entity *oo_get_class_rtti_entity(ir_type *classtype)
172 | {
173 | assert(is_Class_type(classtype));
174 | oo_type_info *ti = get_type_info(classtype);
175 | return ti->rtti;
176 | }
177 |
178 | void oo_set_class_rtti_entity(ir_type *classtype, ir_entity *rtti)
179 | {
180 | assert(is_Class_type(classtype));
181 | oo_type_info *ti = get_type_info(classtype);
182 | ti->rtti = rtti;
183 | }
184 |
185 | ir_entity *oo_get_class_itt_entity(ir_type *classtype)
186 | {
187 | assert(is_Class_type(classtype));
188 | oo_type_info *ti = get_type_info(classtype);
189 | return ti->itt;
190 | }
191 |
192 | void oo_set_class_itt_entity(ir_type *classtype, ir_entity *itt)
193 | {
194 | assert(is_Class_type(classtype));
195 | oo_type_info *ti = get_type_info(classtype);
196 | ti->itt = itt;
197 | }
198 |
199 | bool oo_get_class_is_interface(ir_type *classtype)
200 | {
201 | assert(is_Class_type(classtype));
202 | oo_type_info *ti = get_type_info(classtype);
203 | return ti->flags & oo_is_interface;
204 | }
205 |
206 | void oo_set_class_is_interface(ir_type *classtype, bool is_interface)
207 | {
208 | assert(is_Class_type(classtype));
209 | oo_type_info *ti = get_type_info(classtype);
210 | if (is_interface)
211 | ti->flags |= oo_is_interface;
212 | else
213 | ti->flags &= ~oo_is_interface;
214 | }
215 |
216 | bool oo_get_class_is_abstract(ir_type *classtype)
217 | {
218 | assert(is_Class_type(classtype));
219 | oo_type_info *ti = get_type_info(classtype);
220 | return ti->flags & oo_is_abstract;
221 | }
222 |
223 | void oo_set_class_is_abstract(ir_type *classtype, bool is_abstract)
224 | {
225 | assert(is_Class_type(classtype));
226 | oo_type_info *ti = get_type_info(classtype);
227 | if (is_abstract)
228 | ti->flags |= oo_is_abstract;
229 | else
230 | ti->flags &= ~oo_is_abstract;
231 | }
232 |
233 | bool oo_get_class_is_final(ir_type *classtype)
234 | {
235 | assert(is_Class_type(classtype));
236 | oo_type_info *ti = get_type_info(classtype);
237 | return ti->flags & oo_is_final;
238 | }
239 |
240 | void oo_set_class_is_final(ir_type *classtype, bool is_final)
241 | {
242 | assert(is_Class_type(classtype));
243 | oo_type_info *ti = get_type_info(classtype);
244 | if (is_final)
245 | ti->flags |= oo_is_final;
246 | else
247 | ti->flags &= ~oo_is_final;
248 | }
249 |
250 | bool oo_get_class_is_extern(ir_type *classtype)
251 | {
252 | assert(is_Class_type(classtype));
253 | oo_type_info *ti = get_type_info(classtype);
254 |
255 | return ti->flags & oo_is_extern;
256 | }
257 | void oo_set_class_is_extern(ir_type *classtype, bool is_extern)
258 | {
259 | assert(is_Class_type(classtype));
260 | oo_type_info *ti = get_type_info(classtype);
261 | if (is_extern)
262 | ti->flags |= oo_is_extern;
263 | else
264 | ti->flags &= ~oo_is_extern;
265 |
266 | }
267 |
268 | void *oo_get_type_link(ir_type *type)
269 | {
270 | oo_type_info *ti = get_type_info(type);
271 | return ti->link;
272 | }
273 |
274 | void oo_set_type_link(ir_type *type, void* link)
275 | {
276 | oo_type_info *ti = get_type_info(type);
277 | ti->link = link;
278 | }
279 |
280 | bool oo_get_method_exclude_from_vtable(ir_entity *method)
281 | {
282 | assert(is_method_entity(method));
283 | oo_entity_info *ei = get_entity_info(method);
284 | return ei->exclude_from_vtable;
285 | }
286 |
287 | void oo_set_method_exclude_from_vtable(ir_entity *method, bool exclude_from_vtable)
288 | {
289 | assert(is_method_entity(method));
290 | oo_entity_info *ei = get_entity_info(method);
291 | ei->exclude_from_vtable = exclude_from_vtable;
292 | }
293 |
294 | int oo_get_method_vtable_index(ir_entity *method)
295 | {
296 | assert(is_method_entity(method));
297 | oo_entity_info *ei = get_entity_info(method);
298 | return ei->vtable_index;
299 | }
300 |
301 | void oo_set_method_vtable_index(ir_entity *method, int vtable_index)
302 | {
303 | assert(is_method_entity(method));
304 | oo_entity_info *ei = get_entity_info(method);
305 | ei->vtable_index = vtable_index;
306 | }
307 |
308 | bool oo_get_method_is_abstract(ir_entity *method)
309 | {
310 | assert(is_method_entity(method));
311 | oo_entity_info *ei = get_entity_info(method);
312 | return ei->flags & oo_is_abstract;
313 | }
314 |
315 | void oo_set_method_is_abstract(ir_entity *method, bool is_abstract)
316 | {
317 | assert(is_method_entity(method));
318 | oo_entity_info *ei = get_entity_info(method);
319 | if (is_abstract)
320 | ei->flags |= oo_is_abstract;
321 | else
322 | ei->flags &= ~oo_is_abstract;
323 | }
324 |
325 | bool oo_get_method_is_final(ir_entity *method)
326 | {
327 | assert(is_method_entity(method));
328 | oo_entity_info *ei = get_entity_info(method);
329 | return ei->flags & oo_is_final;
330 | }
331 |
332 | void oo_set_method_is_final(ir_entity *method, bool is_final)
333 | {
334 | assert(is_method_entity(method));
335 | oo_entity_info *ei = get_entity_info(method);
336 | if (is_final)
337 | ei->flags |= oo_is_final;
338 | else
339 | ei->flags &= ~oo_is_final;
340 | }
341 |
342 | bool oo_get_method_is_inherited(ir_entity *method)
343 | {
344 | assert(is_method_entity(method));
345 | oo_entity_info *ei = get_entity_info(method);
346 | return ei->flags & oo_is_inherited;
347 | }
348 |
349 | void oo_set_method_is_inherited(ir_entity *method, bool is_inherited)
350 | {
351 | assert(is_method_entity(method));
352 | oo_entity_info *ei = get_entity_info(method);
353 | if (is_inherited)
354 | ei->flags |= oo_is_inherited;
355 | else
356 | ei->flags &= ~oo_is_inherited;
357 | }
358 |
359 | bool oo_get_field_is_transient(ir_entity *field)
360 | {
361 | assert(!is_method_entity(field));
362 | oo_entity_info *ei = get_entity_info(field);
363 | return ei->flags & oo_is_transient;
364 | }
365 |
366 | void oo_set_field_is_transient(ir_entity *field, bool is_transient)
367 | {
368 | assert(!is_method_entity(field));
369 | oo_entity_info *ei = get_entity_info(field);
370 | if (is_transient)
371 | ei->flags |= oo_is_transient;
372 | else
373 | ei->flags &= ~oo_is_transient;
374 | }
375 |
376 | ddispatch_binding oo_get_entity_binding(ir_entity *entity)
377 | {
378 | oo_entity_info *ei = get_entity_info(entity);
379 | return ei->binding;
380 | }
381 |
382 | void oo_set_entity_binding(ir_entity *entity, ddispatch_binding binding)
383 | {
384 | oo_entity_info *ei = get_entity_info(entity);
385 | ei->binding = binding;
386 | }
387 |
388 | void oo_set_call_is_statically_bound(ir_node *call, bool bind_statically)
389 | {
390 | assert(is_Call(call));
391 | oo_node_info *ni = get_node_info(call);
392 | ni->bind_statically = bind_statically;
393 | }
394 |
395 | bool oo_get_call_is_statically_bound(ir_node *call)
396 | {
397 | assert(is_Call(call));
398 |
399 | /* Shortcut to avoid creating a node_info for each call we see.
400 | * Nearly all calls are bound just like their referenced method
401 | * entity specifies, and just very few (like super.method() in
402 | * Java) must be handled specially. */
403 | if (!pmap_contains(oo_node_info_map, call))
404 | return false;
405 |
406 | oo_node_info *ni = get_node_info(call);
407 | return ni->bind_statically;
408 | }
409 |
410 | void *oo_get_entity_link(ir_entity *entity)
411 | {
412 | oo_entity_info *ei = get_entity_info(entity);
413 | return ei->link;
414 | }
415 |
416 | void oo_set_entity_link(ir_entity *entity, void* link)
417 | {
418 | oo_entity_info *ei = get_entity_info(entity);
419 | ei->link = link;
420 | }
421 |
422 | // Filter out supertypes that are interfaces and return the first real superclass.
423 | ir_type *oo_get_class_superclass(ir_type *klass)
424 | {
425 | assert(is_Class_type(klass));
426 |
427 | ir_type *superclass = NULL;
428 | size_t n_supertyes = get_class_n_supertypes(klass);
429 | for (size_t s = 0; s < n_supertyes; s++) {
430 | ir_type *st = get_class_supertype(klass, s);
431 | if (oo_get_class_is_interface(st))
432 | continue;
433 |
434 | assert(!superclass && "multiple inheritance unsupported");
435 |
436 | superclass = st;
437 | }
438 | return superclass;
439 | }
440 |
441 | // Filter out the overwritten entites that belong to interfaces.
442 | ir_entity *oo_get_entity_overwritten_superclass_entity(ir_entity *entity)
443 | {
444 | assert(is_method_entity(entity));
445 |
446 | ir_entity *superclass_entity = NULL;
447 | size_t n_overwrites = get_entity_n_overwrites(entity);
448 | for (size_t s = 0; s < n_overwrites; s++) {
449 | ir_entity *se = get_entity_overwrites(entity, s);
450 | ir_type *owner = get_entity_owner(se);
451 | assert(owner != get_glob_type());
452 | if (oo_get_class_is_interface(owner))
453 | continue;
454 |
455 | assert(!superclass_entity && "multiple inheritance unsupported");
456 |
457 | superclass_entity = se;
458 | }
459 | return superclass_entity;
460 | }
461 |
462 | void oo_copy_entity_info(ir_entity *src, ir_entity *dest)
463 | {
464 | oo_entity_info *ei_src = get_entity_info(src);
465 | oo_entity_info *ei_dest = get_entity_info(dest);
466 | memcpy(ei_dest, ei_src, sizeof(oo_entity_info));
467 | }
468 |
469 | static void setup_itable_proxy(ir_type *klass, void *env)
470 | {
471 | (void)env;
472 | ddispatch_setup_itable(klass);
473 | }
474 |
475 |
476 | static void setup_vtable_proxy(ir_type *klass, void *env)
477 | {
478 | (void)env;
479 | ddispatch_setup_vtable(klass);
480 | }
481 |
482 | static void construct_runtime_typeinfo_proxy(ir_type *klass, void *env)
483 | {
484 | (void)env;
485 | rtti_construct_runtime_typeinfo(klass);
486 | }
487 |
488 | static void lower_node(ir_node *node, void *env)
489 | {
490 | (void)env;
491 | if (is_Call(node)) {
492 | ddispatch_lower_Call(node);
493 | } else if (is_Arraylength(node)) {
494 | dmemory_lower_Arraylength(node);
495 | } else if (is_InstanceOf(node)) {
496 | rtti_lower_InstanceOf(node);
497 | } else if (is_Proj(node)) {
498 | ir_node *pred = get_Proj_pred(node);
499 | if (is_Raise(pred) && get_Proj_num(node) == pn_Raise_X) {
500 | eh_lower_Raise(pred, node);
501 | } else if (is_VptrIsSet(pred)) {
502 | unsigned pn = get_Proj_num(node);
503 | switch ((pn_VptrIsSet)pn) {
504 | case pn_VptrIsSet_M:
505 | exchange(node, get_VptrIsSet_mem(pred));
506 | return;
507 | case pn_VptrIsSet_res:
508 | exchange(node, get_VptrIsSet_ptr(pred));
509 | return;
510 | }
511 | panic("invalid VptrIsSet Proj");
512 | }
513 | }
514 | }
515 |
516 | static void lower_type(ir_type *type, void *env)
517 | {
518 | (void)env;
519 | assert(is_Class_type(type));
520 |
521 | ir_type *glob = get_glob_type();
522 | if (type == glob)
523 | return;
524 |
525 | int n_members = get_class_n_members(type);
526 | for (int m = n_members-1; m >= 0; m--) {
527 | ir_entity *entity = get_class_member(type, m);
528 | if (!is_method_entity(entity))
529 | continue;
530 | ident *ld_name = get_entity_ld_ident(entity);
531 | ir_entity *ge = ir_get_global(ld_name);
532 | if (NULL != ge) {
533 | /* There is already an entity in global with this name.
534 | * Assume that it is actually the same.
535 | *
536 | * We need this behavior for x10i, because there is no Object class,
537 | * where every class derives from and which owns methods like
538 | * hashCode. Instead there is an Any interface at the top and
539 | * interfaces cannot own methods. This skipping should happen
540 | * exactly for the Any methods.
541 | */
542 | remove_compound_member(type, entity); // TODO free_entity?
543 | } else {
544 | set_entity_owner(entity, glob);
545 | }
546 | /* When changing the entity owner type, the overwrites
547 | * information becomes nonsensical and invalid. */
548 | const size_t n_overwrites = get_entity_n_overwrites(entity);
549 | for (size_t i = 0; i < n_overwrites; ++i) {
550 | ir_entity *over = get_entity_overwrites(entity, 0);
551 | remove_entity_overwrites(entity, over);
552 | }
553 | }
554 | }
555 |
556 | void oo_set_interface_call_type(ddispatch_interface_call type)
557 | {
558 | interface_call_type = type;
559 | }
560 |
561 | ddispatch_interface_call oo_get_interface_call_type()
562 | {
563 | return interface_call_type;
564 | }
565 |
566 | void oo_init(void)
567 | {
568 | obstack_init(&oo_info_obst);
569 | oo_node_info_map = pmap_create();
570 | oo_init_opcodes();
571 | ddispatch_init();
572 | dmemory_init();
573 | rtti_init();
574 | eh_init();
575 | }
576 |
577 | void oo_deinit(void)
578 | {
579 | rtti_deinit();
580 | ddispatch_deinit();
581 | eh_deinit();
582 | obstack_free(&oo_info_obst, NULL);
583 | pmap_destroy(oo_node_info_map);
584 | }
585 |
586 | void oo_lower(void)
587 | {
588 |
589 | ddispatch_interface_call call_type = oo_get_interface_call_type();
590 | if ((call_type & call_searched_itable) == call_searched_itable ||
591 | call_type == call_itable_indexed) {
592 | class_walk_super2sub(setup_itable_proxy, NULL, NULL);
593 | }
594 |
595 | class_walk_super2sub(setup_vtable_proxy, NULL, NULL);
596 | class_walk_super2sub(construct_runtime_typeinfo_proxy, NULL, NULL);
597 |
598 | int n_irgs = get_irp_n_irgs();
599 | for (int i = 0; i < n_irgs; ++i) {
600 | ir_graph *irg = get_irp_irg(i);
601 | irg_walk_graph(irg, NULL, lower_node, NULL);
602 | }
603 |
604 | class_walk_super2sub(lower_type, NULL, NULL);
605 | }
606 |
--------------------------------------------------------------------------------
/src-cpp/opt.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "adt/util.h"
10 | #include "liboo/nodes.h"
11 | #include "liboo/opt.h"
12 |
13 | static bool is_subtype(ir_type *test, ir_type *type)
14 | {
15 | if (test == type)
16 | return true;
17 | for (size_t i = 0, n = get_class_n_supertypes(test); i < n; ++i) {
18 | ir_type *super = get_class_supertype(test, i);
19 | if (is_subtype(super, type))
20 | return true;
21 | }
22 | return false;
23 | }
24 |
25 | static ir_node *transform_node_InstanceOf(ir_node *node)
26 | {
27 | bool result;
28 | ir_node *ptr = get_InstanceOf_ptr(node);
29 | // The null-pointer is not an instance of anything
30 | if (is_Const(ptr) && tarval_is_null(get_Const_tarval(ptr))) {
31 | result = false;
32 | goto make_tuple;
33 | }
34 |
35 | /* if we have a VptrIsSet as predecessor then we can evaluate the
36 | * instanceof right away */
37 | if (!is_Proj(ptr))
38 | return node;
39 | ir_node *pred = get_Proj_pred(ptr);
40 | if (!is_VptrIsSet(pred))
41 | return node;
42 |
43 | ir_type *tested = get_InstanceOf_type(node);
44 | ir_type *actual = get_VptrIsSet_type(pred);
45 | result = is_subtype(actual, tested);
46 |
47 | make_tuple:;
48 | ir_graph *irg = get_irn_irg(node);
49 | ir_node *res = new_r_Const(irg, result ? tarval_b_true : tarval_b_false);
50 | ir_node *tuple_in[] = {
51 | [pn_InstanceOf_M] = get_InstanceOf_mem(node),
52 | [pn_InstanceOf_res] = res,
53 | };
54 | ir_node *block = get_nodes_block(node);
55 | return new_r_Tuple(block, ARRAY_SIZE(tuple_in), tuple_in);
56 | }
57 |
58 | void oo_register_opt_funcs(void)
59 | {
60 | set_op_transform_node(op_InstanceOf, transform_node_InstanceOf);
61 | }
62 |
--------------------------------------------------------------------------------
/src-cpp/rt/error_functions.c:
--------------------------------------------------------------------------------
1 | #include "../adt/error.h"
2 | #include "rt.h"
3 |
4 | void oo_rt_abstract_method_error(void)
5 | {
6 | panic("Cannot invoke abstract method.");
7 | }
8 |
--------------------------------------------------------------------------------
/src-cpp/rt/exceptions.c:
--------------------------------------------------------------------------------
1 | #ifdef LIBOO_EXCEPTION_SUPPORT
2 | #define UNW_LOCAL_ONLY
3 | /* Workaround for buggy glibcs. */
4 | #define _BSD_SOURCE
5 | #include
6 | #undef _BSD_SOURCE
7 |
8 | #include "liboo/rts_types.h"
9 | #include
10 | #include
11 | #include
12 |
13 | extern void firm_personality(void *exception_object);
14 |
15 | extern __thread void *__oo_rt_exception_object__;
16 |
17 | static void oo_rt_unwind(void)
18 | {
19 | unw_cursor_t cursor; unw_context_t uc;
20 | unw_word_t ip;
21 | unw_proc_info_t pi;
22 |
23 | unw_getcontext(&uc);
24 | unw_init_local(&cursor, &uc);
25 |
26 | while (unw_step(&cursor) > 0) {
27 | unw_get_reg(&cursor, UNW_REG_IP, &ip);
28 | unw_get_proc_info(&cursor, &pi);
29 |
30 | if (pi.lsda != 0 && (void (*)(void*))pi.handler == firm_personality) {
31 | lsda_t *lsda = (lsda_t*) pi.lsda;
32 | for (unsigned i = 0; i < lsda->n_entries; i++) {
33 | if (ip == (unsigned)lsda->entries[i].ip) {
34 | unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)lsda->entries[i].handler);
35 | unw_resume(&cursor);
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
42 | __attribute__ ((unused))
43 | void firm_personality(void *exception_object)
44 | {
45 | __oo_rt_exception_object__ = exception_object;
46 | oo_rt_unwind();
47 |
48 | fprintf(stderr, "UNCAUGHT EXCEPTION 0x%p\n", exception_object);
49 | abort();
50 | }
51 | #else
52 | extern void liboo_dummy_func(void);
53 | void liboo_dummy_func(void)
54 | {
55 | }
56 | #endif
57 |
--------------------------------------------------------------------------------
/src-cpp/rt/instanceof.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "../adt/error.h"
3 | #include "rt.h"
4 |
5 | bool oo_rt_instanceof(const class_info_t *objclass,
6 | const class_info_t *refclass)
7 | {
8 | if (objclass == refclass)
9 | return true;
10 |
11 | if (objclass->superclass && oo_rt_instanceof(objclass->superclass, refclass))
12 | return true;
13 |
14 | if (objclass->n_interfaces > 0) {
15 | for (uint32_t i = 0; i < objclass->n_interfaces; i++) {
16 | class_info_t *ci = objclass->interfaces[i];
17 | if (oo_rt_instanceof(ci, refclass))
18 | return true;
19 | }
20 | }
21 |
22 | return false;
23 | }
24 |
--------------------------------------------------------------------------------
/src-cpp/rt/interface_lookup.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "liboo/rts_types.h"
3 | #include "../adt/error.h"
4 | #include "rt.h"
5 | #include "types.h"
6 |
7 | #define ITT_MOVE2FRONT_AREA 5
8 |
9 | void *oo_rt_lookup_interface_method(const class_info_t *klass,
10 | const string_const_t *method_name)
11 | {
12 | const class_info_t *k = klass;
13 | do {
14 | for (uint32_t i = 0; i < k->n_methods; i++) {
15 | const method_info_t *method = &k->methods[i];
16 | if (string_const_equals(method->name, method_name)) {
17 | return method->funcptr;
18 | }
19 | }
20 | // not found, try the superclass
21 | k = k->superclass;
22 | } while (k != NULL);
23 |
24 | panic("Interface lookup for %s in %s failed", get_string_const_chars(method_name), get_string_const_chars(klass->name));
25 | }
26 |
27 | void *oo_searched_itable_method_m2f(const object_t *obj, void *interface_id, int32_t offset)
28 | {
29 | itt_entry_t *itt = obj->vptr->itt;
30 |
31 | int32_t i = itt[0].next;
32 |
33 | int32_t counter = 1;
34 | do {
35 | if (itt[i].id == interface_id) {
36 | void *method = itt[i].itable[offset];
37 |
38 | if (counter > ITT_MOVE2FRONT_AREA) {
39 | if (itt[i].prev > 0)
40 | itt[itt[i].prev].next = itt[i].next;
41 | if (itt[i].next > 0)
42 | itt[itt[i].next].prev = itt[i].prev;
43 |
44 | itt[itt[0].next].prev = i;
45 | itt[i].next = itt[0].next;
46 |
47 | itt[0].next = i;
48 | itt[i].prev = 0;
49 | }
50 |
51 | return method;
52 | }
53 | counter++;
54 | }
55 | while ((i = itt[i].next) > 0);
56 |
57 | panic("itable not found");
58 | }
59 |
60 | void *oo_searched_itable_method(const object_t *obj, void *interface_id, int32_t offset)
61 | {
62 | itt_entry_t *itt = obj->vptr->itt;
63 |
64 | int32_t i = 1;
65 |
66 | int32_t counter = 1;
67 | do {
68 | if (itt[i].id == interface_id) {
69 | return itt[i].itable[offset];
70 | }
71 | counter++;
72 | }
73 | while (itt[++i].id != NULL);
74 |
75 | panic("itable not found");
76 | }
77 |
--------------------------------------------------------------------------------
/src-cpp/rt/rt.h:
--------------------------------------------------------------------------------
1 | #ifndef LIBOO_RT_H
2 | #define LIBOO_RT_H
3 |
4 | #include
5 | #include "liboo/rts_types.h"
6 | #include "types.h"
7 |
8 | /* declarations for runtime interface. (Though most users probably won't use
9 | * this from a C-Compiler... */
10 |
11 | void oo_rt_abstract_method_error(void);
12 | bool oo_rt_instanceof(const class_info_t *objclass,
13 | const class_info_t *refclass);
14 | void *oo_rt_lookup_interface_method(const class_info_t *klass,
15 | const string_const_t *method_name);
16 | void *oo_searched_itable_method(const object_t *obj, void *interface_id,
17 | int32_t offset);
18 | void *oo_searched_itable_method_m2f(const object_t *obj, void *interface_id,
19 | int32_t offset);
20 | #endif
21 |
--------------------------------------------------------------------------------
/src-cpp/rt/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | struct rtti_t {
9 | void *dummy;
10 | };
11 | typedef struct rtti_t rtti_t;
12 |
13 | struct itt_entry_t {
14 | void **itable;
15 | void *id;
16 | int32_t prev;
17 | int32_t next;
18 | };
19 | typedef struct itt_entry_t itt_entry_t;
20 |
21 | struct vtable_t {
22 | rtti_t *rtti;
23 | itt_entry_t *itt;
24 | void *dynamic_methods[];
25 | };
26 | typedef struct vtable_t vtable_t;
27 |
28 | struct object_t {
29 | vtable_t *vptr;
30 | };
31 | typedef struct object_t object_t;
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/src/firm/DebugInfo.java:
--------------------------------------------------------------------------------
1 | package firm;
2 |
3 | import com.sun.jna.Native;
4 | import com.sun.jna.Pointer;
5 |
6 | public class DebugInfo {
7 | static { Native.register("oo"); }
8 | public static native void debuginfo_init();
9 | public static native void debuginfo_deinit();
10 | public static native Pointer create_debuginfo(Pointer filename_ident,
11 | int line, int column,
12 | int length);
13 | }
--------------------------------------------------------------------------------
/src/firm/OO.java:
--------------------------------------------------------------------------------
1 | package firm;
2 |
3 | import com.sun.jna.Pointer;
4 |
5 | import firm.bindings.binding_oo;
6 | import firm.nodes.Node;
7 | import firm.oo.nodes.Nodes;
8 |
9 | /**
10 | * Object-Orientation helper library API
11 | */
12 | public final class OO {
13 | private static boolean initialized;
14 |
15 | public enum InterfaceCallType {
16 | RUNTIME_LOOKUP,
17 | SEARCHED_ITABLE,
18 | INDEXED_ITABLE,
19 | SEARCHED_ITABLE_M2F
20 | }
21 |
22 | private OO() {
23 | }
24 |
25 | /**
26 | * initializes OO library. Must be called once before using any other
27 | * functions from this class.
28 | */
29 | public static void init() {
30 | assert initialized == false; /* we may only use 1 OO object at once... */
31 | binding_oo.oo_init();
32 | Nodes.init();
33 | initialized = true;
34 | }
35 |
36 | /**
37 | * deinitializes OO library. This frees some allocated resources
38 | */
39 | public static void deinit() {
40 | binding_oo.oo_deinit();
41 | initialized = false;
42 | }
43 |
44 | /**
45 | * Lower Object-Oriented constructs into low-level stuff
46 | */
47 | public static void lowerProgram() {
48 | binding_oo.oo_lower();
49 | }
50 |
51 | /**
52 | * Sets the call-type for interface methods
53 | * @param callType
54 | */
55 | public static void setInterfaceLookup(InterfaceCallType callType) {
56 | if (callType == InterfaceCallType.RUNTIME_LOOKUP)
57 | binding_oo.oo_set_interface_call_type(0);
58 | else if (callType == InterfaceCallType.SEARCHED_ITABLE)
59 | binding_oo.oo_set_interface_call_type(1);
60 | else if (callType == InterfaceCallType.INDEXED_ITABLE)
61 | binding_oo.oo_set_interface_call_type(2);
62 | else if (callType == InterfaceCallType.SEARCHED_ITABLE_M2F)
63 | binding_oo.oo_set_interface_call_type(1 | 4);
64 | }
65 |
66 | /**
67 | * lets you configure which methods should be included in the vtable
68 | */
69 | public static void setMethodExcludeFromVTable(Entity entity, boolean includeInVTable) {
70 | binding_oo.oo_set_method_exclude_from_vtable(entity.ptr, includeInVTable);
71 | }
72 |
73 | /**
74 | * lets you mark a method as abstract
75 | */
76 | public static void setMethodAbstract(Entity entity, boolean isAbstract) {
77 | binding_oo.oo_set_method_is_abstract(entity.ptr, isAbstract);
78 | }
79 |
80 | /**
81 | * @return true if method is abstract
82 | */
83 | public static boolean isMethodAbstract(Entity entity) {
84 | return binding_oo.oo_get_method_is_abstract(entity.ptr);
85 | }
86 |
87 | public static void setMethodIsFinal(Entity entity, boolean isFinal) {
88 | binding_oo.oo_set_method_is_final(entity.ptr, isFinal);
89 | }
90 |
91 | public static boolean getMethodIsFinal(Entity entity) {
92 | return binding_oo.oo_get_method_is_final(entity.ptr);
93 | }
94 |
95 | public static void setMethodIsInherited(Entity entity, boolean isInherited) {
96 | binding_oo.oo_set_method_is_inherited(entity.ptr, isInherited);
97 | }
98 |
99 | /**
100 | * @return true if the given field is transient
101 | */
102 | public static boolean getFieldIsTransient(Entity entity) {
103 | return binding_oo.oo_get_field_is_transient(entity.ptr);
104 | }
105 |
106 | /**
107 | * lets you mark a method as transient
108 | */
109 | public static void setFieldIsTransient(Entity entity, boolean isTransient) {
110 | binding_oo.oo_set_field_is_transient(entity.ptr, isTransient);
111 | }
112 |
113 | /**
114 | * lets you specify the binding mode of a method
115 | */
116 | public static void setEntityBinding(Entity entity, binding_oo.ddispatch_binding binding) {
117 | binding_oo.oo_set_entity_binding(entity.ptr, binding.val);
118 | }
119 |
120 | /**
121 | * returns the binding mode of a method
122 | */
123 | public static binding_oo.ddispatch_binding getEntityBinding(Entity entity) {
124 | int binding = binding_oo.oo_get_entity_binding(entity.ptr);
125 | return binding_oo.ddispatch_binding.getEnum(binding);
126 | }
127 |
128 | /**
129 | * Lets you specify static binding for a single call.
130 | * This overwrites any possibly different binding information in the
131 | * method entity referenced by the call.
132 | */
133 | public static void setCallIsStaticallyBound(Node call, boolean isStaticallyBound) {
134 | binding_oo.oo_set_call_is_statically_bound(call.ptr, isStaticallyBound);
135 | }
136 |
137 | /**
138 | * @return the unique compile time type id for the given class type.
139 | */
140 | public static int getClassUID(ClassType classType) {
141 | return binding_oo.oo_get_class_uid(classType.ptr);
142 | }
143 |
144 | /**
145 | * Sets the the unique compile time type id for the given class type.
146 | */
147 | public static void setClassUID(ClassType classType, int uid) {
148 | binding_oo.oo_set_class_uid(classType.ptr, uid);
149 | }
150 |
151 | /**
152 | * @return the previously set vtable entity for the given class type.
153 | */
154 | public static Entity getClassVTableEntity(ClassType classType) {
155 | Pointer vtable = binding_oo.oo_get_class_vtable_entity(classType.ptr);
156 | if (vtable == Pointer.NULL)
157 | return null;
158 | return new Entity(vtable);
159 | }
160 |
161 | /**
162 | * lets you specify the entity containing classType's vtable.
163 | * Use an entity with a primitive pointer type, and set the ld name.
164 | */
165 | public static void setClassVTableEntity(ClassType classType, Entity vtable) {
166 | binding_oo.oo_set_class_vtable_entity(classType.ptr, vtable.ptr);
167 | }
168 |
169 | /**
170 | * lets you specify the entity that represents the pointer to the vtable in an instance
171 | */
172 | public static void setClassVPtrEntity(ClassType classType, Entity entity) {
173 | binding_oo.oo_set_class_vptr_entity(classType.ptr, entity.ptr);
174 | }
175 |
176 | /**
177 | * returns VPTr entity of a class
178 | */
179 | public static Entity getClassVPtrEntity(ClassType classType) {
180 | Pointer res = binding_oo.oo_get_class_vptr_entity(classType.ptr);
181 | if (res == null)
182 | return null;
183 | return new Entity(res);
184 | }
185 |
186 | /**
187 | * lets you specify the entity that represents the run-time type info data.
188 | * Use an entity with a primitive pointer type, and set the ld name.
189 | */
190 | public static void setClassRTTIEntity(ClassType classType, Entity entity) {
191 | binding_oo.oo_set_class_rtti_entity(classType.ptr, entity.ptr);
192 | }
193 |
194 | /**
195 | * lets you specify whether the given classType is representing an interface type
196 | */
197 | public static void setClassIsInterface(ClassType classType, boolean isInterface) {
198 | binding_oo.oo_set_class_is_interface(classType.ptr, isInterface);
199 | }
200 |
201 | public static boolean getClassIsInterface(ClassType classType) {
202 | return binding_oo.oo_get_class_is_interface(classType.ptr);
203 | }
204 |
205 | public static void setClassIsAbstract(ClassType classType, boolean isAbstract) {
206 | binding_oo.oo_set_class_is_abstract(classType.ptr, isAbstract);
207 | }
208 |
209 | public static boolean getClassIsAbstract(ClassType classType) {
210 | return binding_oo.oo_get_class_is_abstract(classType.ptr);
211 | }
212 |
213 | public static void setClassIsFinal(ClassType classType, boolean isFinal) {
214 | binding_oo.oo_set_class_is_final(classType.ptr, isFinal);
215 | }
216 |
217 | public static boolean getClassIsFinal(ClassType classType) {
218 | return binding_oo.oo_get_class_is_final(classType.ptr);
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/firm/RTA.java:
--------------------------------------------------------------------------------
1 | package firm;
2 |
3 | import firm.bindings.binding_rta;
4 |
5 | import com.sun.jna.Pointer;
6 | import java.nio.Buffer;
7 | import java.nio.IntBuffer;
8 | import java.nio.LongBuffer;
9 |
10 | public class RTA {
11 | public static void runRTA(Entity[] entrypoints, Type[] initialLiveClasses) {
12 | binding_rta.rta_optimization(getBufferFromArray(entrypoints, true), getBufferFromArray(initialLiveClasses, true));
13 | }
14 |
15 | private static Buffer getBufferFromArray(JNAWrapper[] array, boolean nullterminate) {
16 | // taken from jFirm source code src/firm/nodes/Node.java and modified it
17 | // This should be placed in firm.JNAWrapper or similar!
18 |
19 | final int length = array.length;
20 |
21 | // There is no PointerBuffer so ...
22 | if (Pointer.SIZE == 4) {
23 | IntBuffer buffer = (nullterminate) ? IntBuffer.allocate(length+1) : IntBuffer.allocate(length);
24 | for (int i = 0; i < length; ++i) {
25 | buffer.put(i, (int) Pointer.nativeValue(array[i].ptr));
26 | }
27 | if (nullterminate)
28 | buffer.put(length, 0);
29 | return buffer;
30 | } else if (Pointer.SIZE == 8) {
31 | LongBuffer buffer = (nullterminate) ? LongBuffer.allocate(length+1) : LongBuffer.allocate(length);
32 | for (int i = 0; i < length; ++i) {
33 | buffer.put(i, Pointer.nativeValue(array[i].ptr));
34 | }
35 | if (nullterminate)
36 | buffer.put(length, 0L);
37 | return buffer;
38 | } else {
39 | /* no 32- or 64-bit architecture */
40 | throw new RuntimeException("Unsupported architecture");
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/firm/bindings/binding_nodes.java:
--------------------------------------------------------------------------------
1 | package firm.bindings;
2 |
3 | /* WARNING: Automatically generated file */
4 | import com.sun.jna.Native;
5 | import com.sun.jna.Pointer;
6 |
7 | public class binding_nodes {
8 | static {
9 | Native.register("oo");
10 | }
11 |
12 | public static enum ir_relation {
13 | ir_relation_false(0),
14 | ir_relation_equal((1 << 0)),
15 | ir_relation_less((1 << 1)),
16 | ir_relation_greater((1 << 2)),
17 | ir_relation_unordered((1 << 3)),
18 | ir_relation_less_equal((ir_relation.ir_relation_equal.val | ir_relation.ir_relation_less.val)),
19 | ir_relation_greater_equal((ir_relation.ir_relation_equal.val | ir_relation.ir_relation_greater.val)),
20 | ir_relation_less_greater((ir_relation.ir_relation_less.val | ir_relation.ir_relation_greater.val)),
21 | ir_relation_less_equal_greater(((ir_relation.ir_relation_equal.val | ir_relation.ir_relation_less.val) | ir_relation.ir_relation_greater.val)),
22 | ir_relation_unordered_equal((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_equal.val)),
23 | ir_relation_unordered_less((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_less.val)),
24 | ir_relation_unordered_less_equal(((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_less.val) | ir_relation.ir_relation_equal.val)),
25 | ir_relation_unordered_greater((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_greater.val)),
26 | ir_relation_unordered_greater_equal(((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_greater.val) | ir_relation.ir_relation_equal.val)),
27 | ir_relation_unordered_less_greater(((ir_relation.ir_relation_unordered.val | ir_relation.ir_relation_less.val) | ir_relation.ir_relation_greater.val)),
28 | ir_relation_true((((ir_relation.ir_relation_equal.val | ir_relation.ir_relation_less.val) | ir_relation.ir_relation_greater.val) | ir_relation.ir_relation_unordered.val));
29 | public final int val;
30 |
31 | private static class C {
32 | static int next_val;
33 | }
34 |
35 | ir_relation(int val) {
36 | this.val = val;
37 | C.next_val = val + 1;
38 | }
39 |
40 | ir_relation() {
41 | this.val = C.next_val++;
42 | }
43 |
44 | public static ir_relation getEnum(int val) {
45 | for (ir_relation entry : values()) {
46 | if (val == entry.val)
47 | return entry;
48 | }
49 | return null;
50 | }
51 | }
52 |
53 | public static enum ir_cons_flags {
54 | cons_none(0),
55 | cons_volatile((1 << 0)),
56 | cons_unaligned((1 << 1)),
57 | cons_floats((1 << 2)),
58 | cons_throws_exception((1 << 3));
59 | public final int val;
60 |
61 | private static class C {
62 | static int next_val;
63 | }
64 |
65 | ir_cons_flags(int val) {
66 | this.val = val;
67 | C.next_val = val + 1;
68 | }
69 |
70 | ir_cons_flags() {
71 | this.val = C.next_val++;
72 | }
73 |
74 | public static ir_cons_flags getEnum(int val) {
75 | for (ir_cons_flags entry : values()) {
76 | if (val == entry.val)
77 | return entry;
78 | }
79 | return null;
80 | }
81 | }
82 |
83 | public static enum op_pin_state {
84 | op_pin_state_floats(0),
85 | op_pin_state_pinned(1),
86 | op_pin_state_exc_pinned();
87 | public final int val;
88 |
89 | private static class C {
90 | static int next_val;
91 | }
92 |
93 | op_pin_state(int val) {
94 | this.val = val;
95 | C.next_val = val + 1;
96 | }
97 |
98 | op_pin_state() {
99 | this.val = C.next_val++;
100 | }
101 |
102 | public static op_pin_state getEnum(int val) {
103 | for (op_pin_state entry : values()) {
104 | if (val == entry.val)
105 | return entry;
106 | }
107 | return null;
108 | }
109 | }
110 |
111 | public static enum cond_jmp_predicate {
112 | COND_JMP_PRED_NONE(),
113 | COND_JMP_PRED_TRUE(),
114 | COND_JMP_PRED_FALSE();
115 | public final int val;
116 |
117 | private static class C {
118 | static int next_val;
119 | }
120 |
121 | cond_jmp_predicate(int val) {
122 | this.val = val;
123 | C.next_val = val + 1;
124 | }
125 |
126 | cond_jmp_predicate() {
127 | this.val = C.next_val++;
128 | }
129 |
130 | public static cond_jmp_predicate getEnum(int val) {
131 | for (cond_jmp_predicate entry : values()) {
132 | if (val == entry.val)
133 | return entry;
134 | }
135 | return null;
136 | }
137 | }
138 |
139 | public static enum mtp_additional_properties {
140 | mtp_no_property(0),
141 | mtp_property_no_write((1 << 0)),
142 | mtp_property_pure((1 << 1)),
143 | mtp_property_noreturn((1 << 2)),
144 | mtp_property_terminates((1 << 3)),
145 | mtp_property_nothrow((1 << 4)),
146 | mtp_property_naked((1 << 5)),
147 | mtp_property_malloc((1 << 6)),
148 | mtp_property_returns_twice((1 << 7)),
149 | mtp_property_private((1 << 8)),
150 | mtp_property_always_inline((1 << 9)),
151 | mtp_property_noinline((1 << 10)),
152 | mtp_property_inline_recommended((1 << 11)),
153 | mtp_temporary((1 << 12));
154 | public final int val;
155 |
156 | private static class C {
157 | static int next_val;
158 | }
159 |
160 | mtp_additional_properties(int val) {
161 | this.val = val;
162 | C.next_val = val + 1;
163 | }
164 |
165 | mtp_additional_properties() {
166 | this.val = C.next_val++;
167 | }
168 |
169 | public static mtp_additional_properties getEnum(int val) {
170 | for (mtp_additional_properties entry : values()) {
171 | if (val == entry.val)
172 | return entry;
173 | }
174 | return null;
175 | }
176 | }
177 |
178 | public static enum ir_builtin_kind {
179 | ir_bk_trap(),
180 | ir_bk_debugbreak(),
181 | ir_bk_return_address(),
182 | ir_bk_frame_address(),
183 | ir_bk_prefetch(),
184 | ir_bk_ffs(),
185 | ir_bk_clz(),
186 | ir_bk_ctz(),
187 | ir_bk_popcount(),
188 | ir_bk_parity(),
189 | ir_bk_bswap(),
190 | ir_bk_inport(),
191 | ir_bk_outport(),
192 | ir_bk_saturating_increment(),
193 | ir_bk_compare_swap(),
194 | ir_bk_may_alias(),
195 | ir_bk_va_start(),
196 | ir_bk_va_arg(),
197 | ir_bk_last(ir_builtin_kind.ir_bk_va_arg.val);
198 | public final int val;
199 |
200 | private static class C {
201 | static int next_val;
202 | }
203 |
204 | ir_builtin_kind(int val) {
205 | this.val = val;
206 | C.next_val = val + 1;
207 | }
208 |
209 | ir_builtin_kind() {
210 | this.val = C.next_val++;
211 | }
212 |
213 | public static ir_builtin_kind getEnum(int val) {
214 | for (ir_builtin_kind entry : values()) {
215 | if (val == entry.val)
216 | return entry;
217 | }
218 | return null;
219 | }
220 | }
221 |
222 | public static enum ir_volatility {
223 | volatility_non_volatile(),
224 | volatility_is_volatile();
225 | public final int val;
226 |
227 | private static class C {
228 | static int next_val;
229 | }
230 |
231 | ir_volatility(int val) {
232 | this.val = val;
233 | C.next_val = val + 1;
234 | }
235 |
236 | ir_volatility() {
237 | this.val = C.next_val++;
238 | }
239 |
240 | public static ir_volatility getEnum(int val) {
241 | for (ir_volatility entry : values()) {
242 | if (val == entry.val)
243 | return entry;
244 | }
245 | return null;
246 | }
247 | }
248 |
249 | public static enum ir_align {
250 | align_is_aligned(0),
251 | align_non_aligned();
252 | public final int val;
253 |
254 | private static class C {
255 | static int next_val;
256 | }
257 |
258 | ir_align(int val) {
259 | this.val = val;
260 | C.next_val = val + 1;
261 | }
262 |
263 | ir_align() {
264 | this.val = C.next_val++;
265 | }
266 |
267 | public static ir_align getEnum(int val) {
268 | for (ir_align entry : values()) {
269 | if (val == entry.val)
270 | return entry;
271 | }
272 | return null;
273 | }
274 | }
275 |
276 | public static enum oo_opcode {
277 | ooo_Arraylength(),
278 | ooo_InstanceOf(),
279 | ooo_MethodSel(),
280 | ooo_VptrIsSet(),
281 | ooo_first(oo_opcode.ooo_Arraylength.val),
282 | ooo_last(oo_opcode.ooo_VptrIsSet.val);
283 | public final int val;
284 |
285 | private static class C {
286 | static int next_val;
287 | }
288 |
289 | oo_opcode(int val) {
290 | this.val = val;
291 | C.next_val = val + 1;
292 | }
293 |
294 | oo_opcode() {
295 | this.val = C.next_val++;
296 | }
297 |
298 | public static oo_opcode getEnum(int val) {
299 | for (oo_opcode entry : values()) {
300 | if (val == entry.val)
301 | return entry;
302 | }
303 | return null;
304 | }
305 | }
306 |
307 | public static enum n_Arraylength {
308 | n_Arraylength_mem(),
309 | n_Arraylength_ptr(),
310 | n_Arraylength_max(n_Arraylength.n_Arraylength_ptr.val);
311 | public final int val;
312 |
313 | private static class C {
314 | static int next_val;
315 | }
316 |
317 | n_Arraylength(int val) {
318 | this.val = val;
319 | C.next_val = val + 1;
320 | }
321 |
322 | n_Arraylength() {
323 | this.val = C.next_val++;
324 | }
325 |
326 | public static n_Arraylength getEnum(int val) {
327 | for (n_Arraylength entry : values()) {
328 | if (val == entry.val)
329 | return entry;
330 | }
331 | return null;
332 | }
333 | }
334 |
335 | public static enum pn_Arraylength {
336 | pn_Arraylength_M(),
337 | pn_Arraylength_res(),
338 | pn_Arraylength_max(pn_Arraylength.pn_Arraylength_res.val);
339 | public final int val;
340 |
341 | private static class C {
342 | static int next_val;
343 | }
344 |
345 | pn_Arraylength(int val) {
346 | this.val = val;
347 | C.next_val = val + 1;
348 | }
349 |
350 | pn_Arraylength() {
351 | this.val = C.next_val++;
352 | }
353 |
354 | public static pn_Arraylength getEnum(int val) {
355 | for (pn_Arraylength entry : values()) {
356 | if (val == entry.val)
357 | return entry;
358 | }
359 | return null;
360 | }
361 | }
362 |
363 | public static enum n_InstanceOf {
364 | n_InstanceOf_mem(),
365 | n_InstanceOf_ptr(),
366 | n_InstanceOf_max(n_InstanceOf.n_InstanceOf_ptr.val);
367 | public final int val;
368 |
369 | private static class C {
370 | static int next_val;
371 | }
372 |
373 | n_InstanceOf(int val) {
374 | this.val = val;
375 | C.next_val = val + 1;
376 | }
377 |
378 | n_InstanceOf() {
379 | this.val = C.next_val++;
380 | }
381 |
382 | public static n_InstanceOf getEnum(int val) {
383 | for (n_InstanceOf entry : values()) {
384 | if (val == entry.val)
385 | return entry;
386 | }
387 | return null;
388 | }
389 | }
390 |
391 | public static enum pn_InstanceOf {
392 | pn_InstanceOf_M(),
393 | pn_InstanceOf_res(),
394 | pn_InstanceOf_max(pn_InstanceOf.pn_InstanceOf_res.val);
395 | public final int val;
396 |
397 | private static class C {
398 | static int next_val;
399 | }
400 |
401 | pn_InstanceOf(int val) {
402 | this.val = val;
403 | C.next_val = val + 1;
404 | }
405 |
406 | pn_InstanceOf() {
407 | this.val = C.next_val++;
408 | }
409 |
410 | public static pn_InstanceOf getEnum(int val) {
411 | for (pn_InstanceOf entry : values()) {
412 | if (val == entry.val)
413 | return entry;
414 | }
415 | return null;
416 | }
417 | }
418 |
419 | public static enum n_MethodSel {
420 | n_MethodSel_mem(),
421 | n_MethodSel_ptr(),
422 | n_MethodSel_max(n_MethodSel.n_MethodSel_ptr.val);
423 | public final int val;
424 |
425 | private static class C {
426 | static int next_val;
427 | }
428 |
429 | n_MethodSel(int val) {
430 | this.val = val;
431 | C.next_val = val + 1;
432 | }
433 |
434 | n_MethodSel() {
435 | this.val = C.next_val++;
436 | }
437 |
438 | public static n_MethodSel getEnum(int val) {
439 | for (n_MethodSel entry : values()) {
440 | if (val == entry.val)
441 | return entry;
442 | }
443 | return null;
444 | }
445 | }
446 |
447 | public static enum pn_MethodSel {
448 | pn_MethodSel_M(),
449 | pn_MethodSel_res(),
450 | pn_MethodSel_max(pn_MethodSel.pn_MethodSel_res.val);
451 | public final int val;
452 |
453 | private static class C {
454 | static int next_val;
455 | }
456 |
457 | pn_MethodSel(int val) {
458 | this.val = val;
459 | C.next_val = val + 1;
460 | }
461 |
462 | pn_MethodSel() {
463 | this.val = C.next_val++;
464 | }
465 |
466 | public static pn_MethodSel getEnum(int val) {
467 | for (pn_MethodSel entry : values()) {
468 | if (val == entry.val)
469 | return entry;
470 | }
471 | return null;
472 | }
473 | }
474 |
475 | public static enum n_VptrIsSet {
476 | n_VptrIsSet_mem(),
477 | n_VptrIsSet_ptr(),
478 | n_VptrIsSet_max(n_VptrIsSet.n_VptrIsSet_ptr.val);
479 | public final int val;
480 |
481 | private static class C {
482 | static int next_val;
483 | }
484 |
485 | n_VptrIsSet(int val) {
486 | this.val = val;
487 | C.next_val = val + 1;
488 | }
489 |
490 | n_VptrIsSet() {
491 | this.val = C.next_val++;
492 | }
493 |
494 | public static n_VptrIsSet getEnum(int val) {
495 | for (n_VptrIsSet entry : values()) {
496 | if (val == entry.val)
497 | return entry;
498 | }
499 | return null;
500 | }
501 | }
502 |
503 | public static enum pn_VptrIsSet {
504 | pn_VptrIsSet_M(),
505 | pn_VptrIsSet_res(),
506 | pn_VptrIsSet_max(pn_VptrIsSet.pn_VptrIsSet_res.val);
507 | public final int val;
508 |
509 | private static class C {
510 | static int next_val;
511 | }
512 |
513 | pn_VptrIsSet(int val) {
514 | this.val = val;
515 | C.next_val = val + 1;
516 | }
517 |
518 | pn_VptrIsSet() {
519 | this.val = C.next_val++;
520 | }
521 |
522 | public static pn_VptrIsSet getEnum(int val) {
523 | for (pn_VptrIsSet entry : values()) {
524 | if (val == entry.val)
525 | return entry;
526 | }
527 | return null;
528 | }
529 | }
530 |
531 |
532 | public static native int is_oo_node(Pointer node);
533 |
534 | public static native /* oo_opcode */int get_oo_irn_opcode(Pointer node);
535 |
536 | public static native Pointer new_rd_Arraylength(Pointer dbgi, Pointer block, Pointer irn_mem, Pointer irn_ptr);
537 |
538 | public static native Pointer new_r_Arraylength(Pointer block, Pointer irn_mem, Pointer irn_ptr);
539 |
540 | public static native Pointer new_d_Arraylength(Pointer dbgi, Pointer irn_mem, Pointer irn_ptr);
541 |
542 | public static native Pointer new_Arraylength(Pointer irn_mem, Pointer irn_ptr);
543 |
544 | public static native int is_Arraylength(Pointer node);
545 |
546 | public static native Pointer get_Arraylength_mem(Pointer node);
547 |
548 | public static native void set_Arraylength_mem(Pointer node, Pointer mem);
549 |
550 | public static native Pointer get_Arraylength_ptr(Pointer node);
551 |
552 | public static native void set_Arraylength_ptr(Pointer node, Pointer ptr);
553 |
554 | public static native Pointer get_op_Arraylength();
555 |
556 | public static native Pointer new_rd_InstanceOf(Pointer dbgi, Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer type);
557 |
558 | public static native Pointer new_r_InstanceOf(Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer type);
559 |
560 | public static native Pointer new_d_InstanceOf(Pointer dbgi, Pointer irn_mem, Pointer irn_ptr, Pointer type);
561 |
562 | public static native Pointer new_InstanceOf(Pointer irn_mem, Pointer irn_ptr, Pointer type);
563 |
564 | public static native int is_InstanceOf(Pointer node);
565 |
566 | public static native Pointer get_InstanceOf_mem(Pointer node);
567 |
568 | public static native void set_InstanceOf_mem(Pointer node, Pointer mem);
569 |
570 | public static native Pointer get_InstanceOf_ptr(Pointer node);
571 |
572 | public static native void set_InstanceOf_ptr(Pointer node, Pointer ptr);
573 |
574 | public static native Pointer get_InstanceOf_type(Pointer node);
575 |
576 | public static native void set_InstanceOf_type(Pointer node, Pointer type);
577 |
578 | public static native Pointer get_op_InstanceOf();
579 |
580 | public static native Pointer new_rd_MethodSel(Pointer dbgi, Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer entity);
581 |
582 | public static native Pointer new_r_MethodSel(Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer entity);
583 |
584 | public static native Pointer new_d_MethodSel(Pointer dbgi, Pointer irn_mem, Pointer irn_ptr, Pointer entity);
585 |
586 | public static native Pointer new_MethodSel(Pointer irn_mem, Pointer irn_ptr, Pointer entity);
587 |
588 | public static native int is_MethodSel(Pointer node);
589 |
590 | public static native Pointer get_MethodSel_mem(Pointer node);
591 |
592 | public static native void set_MethodSel_mem(Pointer node, Pointer mem);
593 |
594 | public static native Pointer get_MethodSel_ptr(Pointer node);
595 |
596 | public static native void set_MethodSel_ptr(Pointer node, Pointer ptr);
597 |
598 | public static native Pointer get_MethodSel_entity(Pointer node);
599 |
600 | public static native void set_MethodSel_entity(Pointer node, Pointer entity);
601 |
602 | public static native Pointer get_op_MethodSel();
603 |
604 | public static native Pointer new_rd_VptrIsSet(Pointer dbgi, Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer type);
605 |
606 | public static native Pointer new_r_VptrIsSet(Pointer block, Pointer irn_mem, Pointer irn_ptr, Pointer type);
607 |
608 | public static native Pointer new_d_VptrIsSet(Pointer dbgi, Pointer irn_mem, Pointer irn_ptr, Pointer type);
609 |
610 | public static native Pointer new_VptrIsSet(Pointer irn_mem, Pointer irn_ptr, Pointer type);
611 |
612 | public static native int is_VptrIsSet(Pointer node);
613 |
614 | public static native Pointer get_VptrIsSet_mem(Pointer node);
615 |
616 | public static native void set_VptrIsSet_mem(Pointer node, Pointer mem);
617 |
618 | public static native Pointer get_VptrIsSet_ptr(Pointer node);
619 |
620 | public static native void set_VptrIsSet_ptr(Pointer node, Pointer ptr);
621 |
622 | public static native Pointer get_VptrIsSet_type(Pointer node);
623 |
624 | public static native void set_VptrIsSet_type(Pointer node, Pointer type);
625 |
626 | public static native Pointer get_op_VptrIsSet();
627 | }
628 |
--------------------------------------------------------------------------------
/src/firm/oo/nodes/Arraylength.java:
--------------------------------------------------------------------------------
1 | /* Warning: Automatically generated file */
2 | package firm.oo.nodes;
3 |
4 | import com.sun.jna.Pointer;
5 | import firm.bindings.binding_ircons;
6 | import firm.nodes.Node;
7 | import firm.nodes.NodeVisitor;
8 | import firm.nodes.NodeWrapperFactory;
9 | import firm.Construction;
10 |
11 | public class Arraylength extends Node {
12 | static class Factory implements NodeWrapperFactory {
13 | @Override
14 | public Node createWrapper(Pointer ptr) {
15 | return new Arraylength(ptr);
16 | }
17 | }
18 |
19 | static void init() {
20 | Pointer op = firm.bindings.binding_nodes.get_op_Arraylength();
21 | Node.registerFactory(firm.bindings.binding_irop.get_op_code(op), new Factory());
22 | }
23 | public static Node create(Node block, Node mem, Node _ptr) {
24 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_Arraylength(block.ptr, mem.ptr, _ptr.ptr));
25 | }
26 |
27 | public static Node create(Construction cons, Node mem, Node _ptr) {
28 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_Arraylength(binding_ircons.get_r_cur_block(cons.getGraph().ptr), mem.ptr, _ptr.ptr));
29 | }
30 |
31 | public Arraylength(Pointer ptr) {
32 | super(ptr);
33 | }
34 |
35 | public Node getMem() {
36 | return createWrapper(firm.bindings.binding_nodes.get_Arraylength_mem(ptr));
37 | }
38 |
39 | public void setMem(Node mem) {
40 | firm.bindings.binding_nodes.set_Arraylength_mem(this.ptr, mem.ptr);
41 | }
42 |
43 | public Node getPtr() {
44 | return createWrapper(firm.bindings.binding_nodes.get_Arraylength_ptr(ptr));
45 | }
46 |
47 | public void setPtr(Node _ptr) {
48 | firm.bindings.binding_nodes.set_Arraylength_ptr(this.ptr, _ptr.ptr);
49 | }
50 |
51 | @Override
52 | public void accept(NodeVisitor visitor) {
53 | visitor.visitUnknown(this);
54 | }
55 |
56 | /** memory result */
57 | public static final int pnM = 0;
58 |
59 | /** length of the array */
60 | public static final int pnRes = 1;
61 |
62 | public static final int pnMax = 2;
63 | }
64 |
--------------------------------------------------------------------------------
/src/firm/oo/nodes/InstanceOf.java:
--------------------------------------------------------------------------------
1 | /* Warning: Automatically generated file */
2 | package firm.oo.nodes;
3 |
4 | import com.sun.jna.Pointer;
5 | import firm.bindings.binding_ircons;
6 | import firm.nodes.Node;
7 | import firm.nodes.NodeVisitor;
8 | import firm.nodes.NodeWrapperFactory;
9 | import firm.Construction;
10 |
11 | public class InstanceOf extends Node {
12 | static class Factory implements NodeWrapperFactory {
13 | @Override
14 | public Node createWrapper(Pointer ptr) {
15 | return new InstanceOf(ptr);
16 | }
17 | }
18 |
19 | static void init() {
20 | Pointer op = firm.bindings.binding_nodes.get_op_InstanceOf();
21 | Node.registerFactory(firm.bindings.binding_irop.get_op_code(op), new Factory());
22 | }
23 | public static Node create(Node block, Node mem, Node _ptr, firm.Type type) {
24 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_InstanceOf(block.ptr, mem.ptr, _ptr.ptr, type.ptr));
25 | }
26 |
27 | public static Node create(Construction cons, Node mem, Node _ptr, firm.Type type) {
28 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_InstanceOf(binding_ircons.get_r_cur_block(cons.getGraph().ptr), mem.ptr, _ptr.ptr, type.ptr));
29 | }
30 |
31 | public InstanceOf(Pointer ptr) {
32 | super(ptr);
33 | }
34 |
35 | public Node getMem() {
36 | return createWrapper(firm.bindings.binding_nodes.get_InstanceOf_mem(ptr));
37 | }
38 |
39 | public void setMem(Node mem) {
40 | firm.bindings.binding_nodes.set_InstanceOf_mem(this.ptr, mem.ptr);
41 | }
42 |
43 | public Node getPtr() {
44 | return createWrapper(firm.bindings.binding_nodes.get_InstanceOf_ptr(ptr));
45 | }
46 |
47 | public void setPtr(Node _ptr) {
48 | firm.bindings.binding_nodes.set_InstanceOf_ptr(this.ptr, _ptr.ptr);
49 | }
50 |
51 | public firm.Type getType() {
52 | Pointer _res = firm.bindings.binding_nodes.get_InstanceOf_type(ptr);
53 | return firm.Type.createWrapper(_res);
54 | }
55 |
56 | public void setType(firm.Type _val) {
57 | firm.bindings.binding_nodes.set_InstanceOf_type(this.ptr, _val.ptr);
58 | }
59 |
60 | @Override
61 | public void accept(NodeVisitor visitor) {
62 | visitor.visitUnknown(this);
63 | }
64 |
65 | /** memory result */
66 | public static final int pnM = 0;
67 |
68 | /** result of instanceof check */
69 | public static final int pnRes = 1;
70 |
71 | public static final int pnMax = 2;
72 | }
73 |
--------------------------------------------------------------------------------
/src/firm/oo/nodes/MethodSel.java:
--------------------------------------------------------------------------------
1 | /* Warning: Automatically generated file */
2 | package firm.oo.nodes;
3 |
4 | import com.sun.jna.Pointer;
5 | import firm.bindings.binding_ircons;
6 | import firm.nodes.Node;
7 | import firm.nodes.NodeVisitor;
8 | import firm.nodes.NodeWrapperFactory;
9 | import firm.Construction;
10 |
11 | public class MethodSel extends Node {
12 | static class Factory implements NodeWrapperFactory {
13 | @Override
14 | public Node createWrapper(Pointer ptr) {
15 | return new MethodSel(ptr);
16 | }
17 | }
18 |
19 | static void init() {
20 | Pointer op = firm.bindings.binding_nodes.get_op_MethodSel();
21 | Node.registerFactory(firm.bindings.binding_irop.get_op_code(op), new Factory());
22 | }
23 | public static Node create(Node block, Node mem, Node _ptr, firm.Entity entity) {
24 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_MethodSel(block.ptr, mem.ptr, _ptr.ptr, entity.ptr));
25 | }
26 |
27 | public static Node create(Construction cons, Node mem, Node _ptr, firm.Entity entity) {
28 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_MethodSel(binding_ircons.get_r_cur_block(cons.getGraph().ptr), mem.ptr, _ptr.ptr, entity.ptr));
29 | }
30 |
31 | public MethodSel(Pointer ptr) {
32 | super(ptr);
33 | }
34 |
35 | public Node getMem() {
36 | return createWrapper(firm.bindings.binding_nodes.get_MethodSel_mem(ptr));
37 | }
38 |
39 | public void setMem(Node mem) {
40 | firm.bindings.binding_nodes.set_MethodSel_mem(this.ptr, mem.ptr);
41 | }
42 |
43 | public Node getPtr() {
44 | return createWrapper(firm.bindings.binding_nodes.get_MethodSel_ptr(ptr));
45 | }
46 |
47 | public void setPtr(Node _ptr) {
48 | firm.bindings.binding_nodes.set_MethodSel_ptr(this.ptr, _ptr.ptr);
49 | }
50 |
51 | public firm.Entity getEntity() {
52 | Pointer _res = firm.bindings.binding_nodes.get_MethodSel_entity(ptr);
53 | return new firm.Entity(_res);
54 | }
55 |
56 | public void setEntity(firm.Entity _val) {
57 | firm.bindings.binding_nodes.set_MethodSel_entity(this.ptr, _val.ptr);
58 | }
59 |
60 | @Override
61 | public void accept(NodeVisitor visitor) {
62 | visitor.visitUnknown(this);
63 | }
64 |
65 | /** memory result */
66 | public static final int pnM = 0;
67 |
68 | /** address of method */
69 | public static final int pnRes = 1;
70 |
71 | public static final int pnMax = 2;
72 | }
73 |
--------------------------------------------------------------------------------
/src/firm/oo/nodes/Nodes.java:
--------------------------------------------------------------------------------
1 | /* Warning: Automatically generated file */
2 | package firm.oo.nodes;
3 |
4 | public class Nodes {
5 | public static void init() {
6 | Arraylength.init();
7 | InstanceOf.init();
8 | MethodSel.init();
9 | VptrIsSet.init();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/firm/oo/nodes/VptrIsSet.java:
--------------------------------------------------------------------------------
1 | /* Warning: Automatically generated file */
2 | package firm.oo.nodes;
3 |
4 | import com.sun.jna.Pointer;
5 | import firm.bindings.binding_ircons;
6 | import firm.nodes.Node;
7 | import firm.nodes.NodeVisitor;
8 | import firm.nodes.NodeWrapperFactory;
9 | import firm.Construction;
10 |
11 | public class VptrIsSet extends Node {
12 | static class Factory implements NodeWrapperFactory {
13 | @Override
14 | public Node createWrapper(Pointer ptr) {
15 | return new VptrIsSet(ptr);
16 | }
17 | }
18 |
19 | static void init() {
20 | Pointer op = firm.bindings.binding_nodes.get_op_VptrIsSet();
21 | Node.registerFactory(firm.bindings.binding_irop.get_op_code(op), new Factory());
22 | }
23 | public static Node create(Node block, Node mem, Node _ptr, firm.Type type) {
24 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_VptrIsSet(block.ptr, mem.ptr, _ptr.ptr, type.ptr));
25 | }
26 |
27 | public static Node create(Construction cons, Node mem, Node _ptr, firm.Type type) {
28 | return Node.createWrapper(firm.bindings.binding_nodes.new_r_VptrIsSet(binding_ircons.get_r_cur_block(cons.getGraph().ptr), mem.ptr, _ptr.ptr, type.ptr));
29 | }
30 |
31 | public VptrIsSet(Pointer ptr) {
32 | super(ptr);
33 | }
34 |
35 | public Node getMem() {
36 | return createWrapper(firm.bindings.binding_nodes.get_VptrIsSet_mem(ptr));
37 | }
38 |
39 | public void setMem(Node mem) {
40 | firm.bindings.binding_nodes.set_VptrIsSet_mem(this.ptr, mem.ptr);
41 | }
42 |
43 | public Node getPtr() {
44 | return createWrapper(firm.bindings.binding_nodes.get_VptrIsSet_ptr(ptr));
45 | }
46 |
47 | public void setPtr(Node _ptr) {
48 | firm.bindings.binding_nodes.set_VptrIsSet_ptr(this.ptr, _ptr.ptr);
49 | }
50 |
51 | public firm.Type getType() {
52 | Pointer _res = firm.bindings.binding_nodes.get_VptrIsSet_type(ptr);
53 | return firm.Type.createWrapper(_res);
54 | }
55 |
56 | public void setType(firm.Type _val) {
57 | firm.bindings.binding_nodes.set_VptrIsSet_type(this.ptr, _val.ptr);
58 | }
59 |
60 | @Override
61 | public void accept(NodeVisitor visitor) {
62 | visitor.visitUnknown(this);
63 | }
64 |
65 | /** memory result */
66 | public static final int pnM = 0;
67 |
68 | /** pointer to object */
69 | public static final int pnRes = 1;
70 |
71 | public static final int pnMax = 2;
72 | }
73 |
--------------------------------------------------------------------------------