1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.objectweb.fractal.cecilia.primitive.thinkMC.implementations;
25
26 import static org.objectweb.fractal.adl.NodeUtil.castNodeError;
27 import static org.objectweb.fractal.cecilia.adl.SourceCodeHelper.appendSortedSourceCodes;
28 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationHelper.hasConstructor;
29 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationHelper.hasDestructor;
30 import static org.objectweb.fractal.cecilia.adl.SourceCodeHelper.appendReverseSortedSourceCodes;
31
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import org.objectweb.fractal.adl.ADLException;
37 import org.objectweb.fractal.adl.CompilerError;
38 import org.objectweb.fractal.adl.ComponentVisitor;
39 import org.objectweb.fractal.adl.Node;
40 import org.objectweb.fractal.adl.components.ComponentContainer;
41 import org.objectweb.fractal.adl.error.GenericErrors;
42 import org.objectweb.fractal.adl.implementations.ImplementationContainer;
43 import org.objectweb.fractal.api.Component;
44 import org.objectweb.fractal.cecilia.adl.AbstractDefinitionTask;
45 import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
46 import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
47 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
48 import org.objectweb.fractal.task.core.TaskException;
49 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
50 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
51 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
52 import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
53
54 public class FactoryImplementationVisitor extends AbstractTaskFactoryUser
55 implements
56 ComponentVisitor {
57
58
59
60
61
62
63
64
65
66
67 public Component visit(final List<Node> path,
68 final ComponentContainer container, final Map<Object, Object> context)
69 throws ADLException, TaskException {
70 if (castNodeError(container, ImplementationContainer.class)
71 .getImplementation() == null) {
72 throw new CompilerError(GenericErrors.INTERNAL_ERROR,
73 "This visitor is only applicable for primitive component.");
74 }
75 return taskFactoryItf.newPrimitiveTask(new FactoryImplementationTask(
76 hasConstructor(container), hasDestructor(container)), container);
77 }
78
79
80
81
82
83
84
85
86
87 @TaskParameters("componentNode")
88 @ServerInterfaces(@ServerInterface(name = "factory-implementation", signature = SourceCodeProvider.class, record = "role:factoryImplementation, id:%", parameters = "componentNode"))
89 public static class FactoryImplementationTask extends AbstractDefinitionTask {
90
91 protected final boolean hasConstructor;
92 protected final boolean hasDestructor;
93
94
95
96
97
98
99
100
101
102
103 public FactoryImplementationTask(final boolean hasConstructor,
104 final boolean hasDestructor) {
105 this.hasConstructor = hasConstructor;
106 this.hasDestructor = hasDestructor;
107 }
108
109
110
111
112
113
114
115
116
117
118 @ClientInterface(name = "factory-instantiate-declaration", signature = SourceCodeProvider.class, record = "role:factoryInstantiateDeclaration, id:%", parameters = "componentNode")
119 public final Map<String, SourceCodeProvider> factoryInstantiateDeclarationProviderItfs = new HashMap<String, SourceCodeProvider>();
120
121
122
123
124
125
126 @ClientInterface(name = "factory-instantiate-sizeof", signature = SourceCodeProvider.class, record = "role:factoryInstantiateSizeof, id:%", parameters = "componentNode")
127 public final Map<String, SourceCodeProvider> factoryInstantiateSizeofProviderItfs = new HashMap<String, SourceCodeProvider>();
128
129
130
131
132
133 @ClientInterface(name = "factory-instantiate-codes-pieces", signature = SourceCodeProvider.class, record = "role:factoryInstantiatePiece, id:%", parameters = "componentNode")
134 public final Map<String, SourceCodeProvider> factoryInstantiatePieceProviderItfs = new HashMap<String, SourceCodeProvider>();
135
136
137
138
139
140 @Override
141 protected String processSourceCode() throws Exception {
142 final CodeWriter cw = new CodeWriter(
143 "Primitive Factory Implementation Builder");
144 final String componentCName = typeNameProviderItf.getCTypeName();
145
146 cw.append("#include <string.h>").endl();
147
148
149
150 cw.append("int ").append("METHOD(factory, newFcInstance)(void * _this, ")
151 .append("Rfractal_api_Component ** instance) {").endl();
152 cw.append("struct ").append(componentCName).append("_t *originalComp = ")
153 .append("(struct ").append(componentCName).append("_t *) _this;")
154 .endl();
155 cw.append("struct ").append(componentCName).append("_t *newComp = (")
156 .append("struct ").append(componentCName).append(
157 "_t *) CALL(REQUIRED.factory_allocator, alloc,").append(
158 "sizeof(struct ").append(componentCName).append("_t)");
159
160 appendReverseSortedSourceCodes(cw, factoryInstantiateSizeofProviderItfs
161 .values());
162
163 cw.appendln(");");
164 cw.appendln("unsigned char *_ptr = (unsigned char *)newComp;");
165
166 appendReverseSortedSourceCodes(cw,
167 factoryInstantiateDeclarationProviderItfs.values());
168
169 cw.append("memcpy(newComp, originalComp, sizeof(struct ").append(
170 componentCName).append("_t));").endl();
171 cw.append("_ptr += sizeof(struct ").append(componentCName).append("_t);")
172 .endl();
173
174 appendReverseSortedSourceCodes(cw, factoryInstantiatePieceProviderItfs
175 .values());
176
177 cw.append("*instance = & (newComp->type.exported.component);").endl();
178 if (hasConstructor) {
179 cw.append(componentCName).append("_constructor(newComp); ").endl();
180 }
181
182 cw.append("return fractal_api_ErrorConst_OK;").endl();
183
184 cw.append("}").endl().endl();
185
186
187
188 cw.append("int METHOD(factory, destroyFcInstance)").append(
189 "(void * _this, Rfractal_api_Component *comp) {").endl();
190 cw.append("struct ").append(componentCName)
191 .append("_t *originalComp = (").append("struct ").append(
192 componentCName).append("_t *) comp;").endl();
193
194 if (hasDestructor) {
195 cw.append(componentCName).append("_destructor(comp); ").endl();
196 }
197
198 cw.append(
199 "CALL(REQUIRED.factory_allocator, free, (jbyte *) originalComp);")
200 .endl();
201 cw.append("return fractal_api_ErrorConst_OK;").endl();
202
203 cw.append("}").endl().endl();
204
205 return cw.toString();
206 }
207 }
208 }