1 package com.tapina.robe.swi.clib.stdlib;
2
3 import com.tapina.robe.runtime.CodeBlock;
4 import com.tapina.robe.runtime.Environment;
5 import com.tapina.robe.swi.clib.Stub;
6
7 import java.util.Arrays;
8 import java.util.Comparator;
9
10 /***
11 * This function sorts an array of a2 objects, each of which is a3 bytes long, and whose first object is pointed
12 * to by a1 into ascending order.
13 * The function a4 which must be defined by you is called with pointers to objects. If the first is less than, equal
14 * to, or greater than the second then the function should return less than, equal to, or greater than zero.
15 */
16 public class QSort extends Stub {
17 public void executeStub(final Environment environment) {
18 final int R[] = environment.getCpu().R;
19 final int numObjects = R[1];
20 final int objectSize = R[2];
21 final int baseAddress = R[0];
22 final int functionAddress = R[3];
23
24
25 final Integer[] objectAddresses = new Integer[numObjects];
26 for (int i = 0; i < numObjects; i++) {
27 objectAddresses[i] = new Integer(baseAddress + i * objectSize);
28 }
29
30 final CodeBlock function = environment.getMemoryMap().addEntryPoint(functionAddress);
31 final Comparator comparator = new Comparator() {
32 /***
33 * This Comparator takes two Integer parameters. It passes those parameters (which are addresses)
34 * to the underlying C function for evaluation.
35 * @param o1 Integer address 1
36 * @param o2 Integer address 2
37 * @return Less than 0, 0, or greater than 0.
38 */
39 public int compare(Object o1, Object o2) {
40 Integer i1 = (Integer) o1;
41 Integer i2 = (Integer) o2;
42 R[0] = i1.intValue();
43 R[1] = i2.intValue();
44 executeSubroutine(environment, function);
45 return R[0];
46 }
47 };
48
49
50 Arrays.sort(objectAddresses, comparator);
51
52 final byte[][] output = new byte[numObjects][];
53
54
55 for (int i = 0; i < numObjects; i++) {
56 final int objectAddress = objectAddresses[i].intValue();
57 output[i] = environment.getMemoryMap().getBytes(objectAddress, objectSize);
58 }
59
60
61 for (int i = 0; i < output.length; i++) {
62 final int outputAddress = baseAddress + i * objectSize;
63 environment.getMemoryMap().storeBytes(outputAddress, output[i], 0, output[i].length);
64 }
65 }
66 }