blob: 22759e0669cb005679862a2c10476663ca8eb828 [file] [log] [blame]
Shih-wei Liao19cc6972011-01-20 04:34:38 -08001=========================================
2llvm-rs-cc: Compiler for ScriptC language
3=========================================
4
5
6Introduction
7------------
8
9llvm-rs-cc compiles a program in the ScriptC language to generate the
10following files.
11
12* Bitcode file. Note that the bitcode here denotes the LLVM (Low-Level
13 Virtual Machine) bitcode representation, which will be consumed on
14 an Android device by libbcc (in
15 platform/frameworks/compile/libbcc.git) to generate device-specific
16 executables.
17
18* Reflected APIs for Java. As a result, Android's Java developers can
19 invoke those APIs from their code.
20
21Note that although ScriptC is C99-like, we enhance it with several
22distinct, effective features for Android programming. We will use
23example usage below to illustrate these features.
24
25llvm-rs-cc is being run on a host and is highly-optimizing. As a
26result, libbcc on the device can be lightweight and focus on
27machine-dependent code generation given some bitcode.
28
29llvm-rs-cc is a driver on top of libslang. The archictecture of
30libslang and libbcc is depicted in the following figure::
31
32 libslang libbcc
33 | \ |
34 | \ |
35 clang llvm
36
37
38Usage
39-----
40
41* *-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw*
42
43 This option specifies the directory for outputting a .bc file.
44
45* *-p $(PRIVATE_RS_OUTPUT_DIR)/src*
46
47 The option *-p* denotes the directory for outputting the reflected Java files.
48
49* *-d $(PRIVATE_RS_OUTPUT_DIR)*
50
51 This option *-d* sets the directory for writing dependences.
52
53* *-MD*
54
55 Note that *-MD* will tell llvm-rs-cc to output dependences.
56
Shih-wei Liao29c36732011-01-20 05:48:20 -080057* *-a*
58
59 Specifies additional dependence target.
Shih-wei Liao19cc6972011-01-20 04:34:38 -080060
61Example Command
62---------------
63
64First::
65
66 $ cd <Android_Root_Directory>
67
68Using frameworks/base/libs/rs/java/Fountain as a simple app in both
69Java and ScriptC, we can find the following command line in the build
70log::
71
72 $ out/host/linux-x86/bin/llvm-rs-cc \
73 -o out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/res/raw \
74 -p out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/src \
75 -d out/target/common/obj/APPS/Fountain_intermediates/src/renderscript \
76 -a out/target/common/obj/APPS/Fountain_intermediates/src/RenderScript.stamp \
77 -MD \
78 -I frameworks/base/libs/rs/scriptc \
79 -I external/clang/lib/Headers \
80 frameworks/base/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
81
82This command will generate:
83
84* **fountain.bc**
85
86* **ScriptC_fountain.java**
87
88* **ScriptField_Point.java**
89
90The **Script\*.java** files above will be documented below.
91
92
93Example Program: fountain.rs
94----------------------------
95
96fountain.rs is in ScriptC language, which is based on the standard
97C99. However, llvm-rs-cc goes beyond "clang -std=c99" and provides the
98following important features:
99
1001. Pragma
101---------
102
103* *#pragma rs java_package_name([PACKAGE_NAME])*
104
105 The ScriptC_[SCRIPT_NAME].java has to be packaged so that Java
106 developers can invoke those APIs.
107
108 To do that, a ScriptC programmer should specify the package name, so
109 that llvm-rs-cc knows the package expression and hence the directory
110 for outputting ScriptC_[SCRIPT_NAME].java.
111
112 In fountain.rs, we have::
113
114 #pragma rs java_package_name(com.android.fountain)
115
116 In ScriptC.fountain.java, we have::
117
118 package com.android.fountain
119
120 Note that the ScriptC_fountain.java will be generated inside
121 ./com/android/fountain/.
122
123* #pragma version(1)
124
125 This pragma is for evolving the language. Currently we are at
126 version 1 of the language.
127
128
1292. Basic Reflection: Export Variables and Functions
130---------------------------------------------------
131
132llvm-rs-cc automatically export the "externalizable and defined" functions and
133variables to Android's Java side. That is, scripts are accessible from
134Java.
135
136For instance, for::
137
138 int foo = 0;
139
140In ScriptC_fountain.java, llvm-rs-cc will reflect it to::
141
142 void set_foo(int v)...
143
144 int get_foo()...
145
146This access takes the form of generated classes which provide access
147to the functions and global variables within a script. In summary,
148global variables and functions within a script that are not declared
149static will generate get, set, or invoke methods. This provides a way
150to set the data within a script and call to its functions.
151
152Take the addParticles function in fountain.rs as an example::
153
154 void addParticles(int rate, float x, float y, int index, bool newColor) {
155 ...
156 }
157
158llvm-rs-cc will genearte ScriptC_fountain.java as follows::
159
160 void invoke_addParticles(int rate, float x, float y,
161 int index, bool newColor) {
162 ...
163 }
164
165
1663. Export User-Defined Structs
167------------------------------
168
169In fountain.rs, we have::
170
171 typedef struct __attribute__((packed, aligned(4))) Point {
172 float2 delta;
173 float2 position;
174 uchar4 color;
175 } Point_t;
176
177 Point_t *point;
178
179llvm-rs-cc generates one ScriptField*.java file for each user-defined
180struct. I.e., in this case llvm-rs-cc will reflect to two files,
181ScriptC_fountain.java and ScriptField_Point.java.
182
183Note that when the type of exportable variable is struct, ScriptC
184developers should avoid anonymous structs. This is because llvm-rs-cc
185uses the struct name to name the file, instead of the typedef name.
186
187For the generated Java files, using ScriptC_fountain.java as an
188example we have::
189
190 void bind_point(ScriptField_Point v)
191
192This binds your object with the allocated memory.
193
194You can bind the struct(e.g., Point), using the setter and getter
195method in ScriptField_Point.java.
196
197After binding, you could get the object from this method::
198
199 ScriptField_Point get_point()
200
201In ScriptField_Point_s.java::
202
203 ...
204 // Copying the Item, which is the object that stores every
205 // fields of struct, to the *index*\-th entry of byte array.
206 //
207 // In general, this method would not be invoked directly
208 // but is used to implement the setter.
209 void copyToArray(Item i, int index)
210
211 // The setter of Item array,
212 // index: the index of the Item array
213 // copyNow: If true, it will be copied to the *index*\-th entry
214 // of byte array.
215 void set(Item i, int index, boolean copyNow)
216
217 // The getter of Item array, which gets the *index*-th element
218 // of byte array.
219 Item get(int index)
220
221 set_delta(int index, Float2 v, boolean copyNow)
222
223 // The following is the individual setters and getters of
224 // each field of a struct.
225 public void set_delta(int index, Float2 v, boolean copyNow)
226 public void set_position(int index, Float2 v, boolean copyNow)
227 public void set_color(int index, Short4 v, boolean copyNow)
228 public Float2 get_delta(int index)
229 public Float2 get_position(int index)
230 public Short4 get_color(int index)
231
232 // Copying all Item array to byte array (i.e., memory allocation).
233 void copyAll()
234 ...
235
236
2374. Summarize the Java Reflection above
238--------------------------------------
239
240Let us summarize the high-level design of reflection next.
241
242* In terms of script's global functions, they can be called from Java.
243 These calls operate asynchronously and no assumptions should be made
244 upon with a function called will actually complete operation. If it
245 is necessary to wait for a function to complete the java application
246 may call the runtime finish method which will wait for all the script
247 threads to complete. Two special functions also exist:
248
249 * The function **init** present will be called once after the script
250 is loaded. This is useful to initialize data or anything else the
251 script may need before it can be used. The init may not depend on
252 globals initialized from Java as it will be called before these
253 can be initialized.
254
255 * The function **root** is a special function for graphics. Which a
256 script must redraw its contents this function will be called. No
257 assumptions should be made as to when this function will be
258 called. It will only be called if the script is bound as root.
259 Also calls to this will be synchronized with data updates and
260 other invocations from Java. Thus the script will not change due
261 to external influence during a run of **root**. The return value
262 indicates to the runtime if the function should be called again to
263 redraw in the future. A return value of 0 indicates that no
264 redraw is necessary until something changes. Any positive integer
265 indicates a time in ms that the runtime should wait before calling
266 root again to render another frame.
267
268* In terms of script's global data, global variables can be written
269 from Java. The Java class will cache the value or object set and
270 provide return methods to retrieve this value. If a script updates
271 the value, this update will not propagate back to the Java class.
272 Initializers if present will also initialize the cached Java value.
273 This provides a convenient way to declare constants within a script and
274 make them accessible from the java runtime. If the script declares a
275 variable const, only the get methods will be generated.
276
277 Globals within a script are considered local to the script. They
278 cannot be accessed by other scripts and are in effect always 'static'
279 in the traditional C sense. Static here is used to control if a
280 accessor is generated. Static continues to mean *not
281 externally visible* and thus prevents the generation of
282 accessors. Globals are persistent across invocations to a script and
283 thus may be used to hold data from run to run.
284
285 Globals of two types may be reflected into the Java class. The first
286 type is basic non-pointer types. Types defined in rs_types.rsh may be
287 used. For the non-pointer class get and set methods are generated in
288 Java. Globals of single pointer types behave differently. These may
289 use more complex types. Simple structures composed of the types in
290 rs_types.rsh may also be used. These globals generate bind points in
291 java. If the type is a structure they also generate a **Field** class
292 used to pack and unpack the contents of the structure. Binding an
293 allocation to one of these bind points in Java effectively sets the
294 pointer in the script. Bind points marked const indicate to the
295 runtime that the script will not modify the contents of an allocation.
296 This may allow the runtime to make more effective use of threads.
297
298
2995. Vector Types
300---------------
301
302Vector types such as float2, float4, and uint4 are included to support
303vector processing in environments where the processors provide vector
304instructions.
305
306On non-vector systems the same code will continue to run but without
307the performance advantage. Function overloading is also supported.
308This allows the runtime to support vector version of the basic math
309routines without the need for special naming. For instance,
310
311* *float sin(float);*
312
313* *float2 sin(float2);*
314
315* *float4 sin(float4);*