Merge lp:~larryprice/ciborium/go1.6-port into lp:ciborium

Proposed by Larry Price
Status: Merged
Approved by: Stephen M. Webb
Approved revision: 159
Merged at revision: 159
Proposed branch: lp:~larryprice/ciborium/go1.6-port
Merge into: lp:ciborium
Diff against target: 797 lines (+162/-110)
11 files modified
cmd/ciborium-ui/main.go (+9/-4)
qml.v1/bridge.go (+63/-25)
qml.v1/cpp/capi.cpp (+15/-15)
qml.v1/cpp/capi.h (+20/-19)
qml.v1/cpp/connector.h (+2/-2)
qml.v1/cpp/govalue.cpp (+16/-16)
qml.v1/cpp/govalue.h (+4/-4)
qml.v1/cpp/govaluetype.cpp (+6/-6)
qml.v1/cpp/govaluetype.h (+4/-4)
qml.v1/datatype.go (+1/-2)
qml.v1/qml.go (+22/-13)
To merge this branch: bzr merge lp:~larryprice/ciborium/go1.6-port
Reviewer Review Type Date Requested Status
Stephen M. Webb (community) Approve
Review via email: mp+297801@code.launchpad.net

Commit message

Fix crash on startup hopefully related to bug #1592421.

Description of the change

Fix crash on startup hopefully related to bug #1592421.

As far as I can tell, this crash was happening due to a new cgo error that only happens in go1.6. My assumption is that the binary was compiled using go1.6. go-qml has related bug https://github.com/go-qml/qml/issues/170. I merged https://github.com/SjB/qml/tree/go1.6-port into the local qml.v1 directory to swipe the fixes for this issue. Hopefully eventually this will become a PR and get officially merged into go-qml.v1.

I also adjusted the syntax being used to run the application with go-qml to get better error reporting. With the old method, I saw a simple stacktrace with no useful information. With the new method, I was able to see: `panic: runtime error: cgo argument has Go pointer to Go pointer` which led me to this particular solution.

To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) wrote :

Seems to fix the crash. Tested on m10.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/ciborium-ui/main.go'
2--- cmd/ciborium-ui/main.go 2015-06-11 10:35:19 +0000
3+++ cmd/ciborium-ui/main.go 2016-06-17 18:52:58 +0000
4@@ -77,14 +77,18 @@
5 // set default logger flags to get more useful info
6 log.SetFlags(log.LstdFlags | log.Lshortfile)
7
8- // not in qml.v1
9- //qml.Init(nil)
10+ err := qml.Run(run)
11+ if err != nil {
12+ log.Fatal(err)
13+ }
14+}
15+
16+func run() error {
17 engine := qml.NewEngine()
18 component, err := engine.LoadFile(mainQmlPath)
19 if err != nil {
20- log.Fatal(err)
21+ return err
22 }
23-
24 context := engine.Context()
25
26 driveCtrl, err := newDriveControl()
27@@ -98,6 +102,7 @@
28
29 window.Show()
30 window.Wait()
31+ return nil
32 }
33
34 func newDriveControl() (*driveControl, error) {
35
36=== modified file 'qml.v1/bridge.go'
37--- qml.v1/bridge.go 2015-06-11 10:25:43 +0000
38+++ qml.v1/bridge.go 2016-06-17 18:52:58 +0000
39@@ -203,6 +203,35 @@
40 owner valueOwner
41 }
42
43+// cgoFolds holds all fold values that get reference to on the cgo space.
44+// Since Go Pointer are not allowed to be held by cgo. We need a lookup
45+// table to interface the two space.
46+var cgoFolds = make(map[C.GoRef]*valueFold)
47+
48+// GoRef index the valueFold value and return a lookup
49+// key (C.GoRef), so that we can retrieve the fold using
50+// the C.GoRef. need to cross between go and cgo
51+func (f *valueFold) goRef() C.GoRef {
52+ ref := C.GoRef(uintptr(unsafe.Pointer(f)))
53+ cgoFolds[ref] = f
54+ return ref
55+}
56+
57+// destroyRef remove the valueFold reference from the lookup table.
58+func (f *valueFold) destroyRef() {
59+ ref := C.GoRef(uintptr(unsafe.Pointer(f)))
60+ delete(cgoFolds, ref)
61+}
62+
63+// getFoldFromGoRef return the valueFold value located at ref
64+func getFoldFromGoRef(ref C.GoRef) *valueFold {
65+ fold := cgoFolds[ref]
66+ if fold == nil {
67+ panic("cannot find fold go reference")
68+ }
69+ return fold
70+}
71+
72 type valueOwner uint8
73
74 const (
75@@ -251,7 +280,7 @@
76 gvalue: gvalue,
77 owner: owner,
78 }
79- fold.cvalue = C.newGoValue(unsafe.Pointer(fold), typeInfo(gvalue), parent)
80+ fold.cvalue = C.newGoValue(fold.goRef(), typeInfo(gvalue), parent)
81 if prev != nil {
82 // Put new fold first so the single cppOwner, if any, is always the first entry.
83 fold.next = prev
84@@ -289,29 +318,37 @@
85 var typeNew = make(map[*valueFold]bool)
86
87 //export hookGoValueTypeNew
88-func hookGoValueTypeNew(cvalue unsafe.Pointer, specp unsafe.Pointer) (foldp unsafe.Pointer) {
89+func hookGoValueTypeNew(cvalue unsafe.Pointer, specr C.GoTypeSpec_) (foldr C.GoRef) {
90 // Initialization is postponed until the engine is available, so that
91 // we can hand Init the qml.Object that represents the object.
92- init := reflect.ValueOf((*TypeSpec)(specp).Init)
93+ spec := types[specr]
94+ if spec == nil {
95+ panic("cannot find the specified TypeSpec")
96+ }
97+
98+ init := reflect.ValueOf(spec.Init)
99 fold := &valueFold{
100 init: init,
101 gvalue: reflect.New(init.Type().In(0).Elem()).Interface(),
102 cvalue: cvalue,
103 owner: jsOwner,
104 }
105+
106 typeNew[fold] = true
107 //fmt.Printf("[DEBUG] value alive (type-created): cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
108 stats.valuesAlive(+1)
109- return unsafe.Pointer(fold)
110+ return fold.goRef()
111 }
112
113 //export hookGoValueDestroyed
114-func hookGoValueDestroyed(enginep unsafe.Pointer, foldp unsafe.Pointer) {
115- fold := (*valueFold)(foldp)
116+func hookGoValueDestroyed(enginep unsafe.Pointer, foldr C.GoRef) {
117+ fold := getFoldFromGoRef(foldr)
118+
119 engine := fold.engine
120 if engine == nil {
121 before := len(typeNew)
122 delete(typeNew, fold)
123+ fold.destroyRef()
124 if len(typeNew) == before {
125 panic("destroying value without an associated engine; who created the value?")
126 }
127@@ -342,6 +379,7 @@
128 delete(engines, engine.addr)
129 }
130 }
131+ fold.destroyRef()
132 }
133 //fmt.Printf("[DEBUG] value destroyed: cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
134 stats.valuesAlive(-1)
135@@ -360,8 +398,8 @@
136 }
137
138 //export hookGoValueReadField
139-func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue) {
140- fold := ensureEngine(enginep, foldp)
141+func hookGoValueReadField(enginep unsafe.Pointer, foldr C.GoRef, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue) {
142+ fold := ensureEngine(enginep, foldr)
143
144 var field reflect.Value
145 if getIndex >= 0 {
146@@ -376,7 +414,7 @@
147 // TODO Handle getters that return []qml.Object.
148 // TODO Handle other GoValue slices (!= []qml.Object).
149 resultdv.dataType = C.DTListProperty
150- *(*unsafe.Pointer)(unsafe.Pointer(&resultdv.data)) = C.newListProperty(foldp, C.intptr_t(reflectIndex), C.intptr_t(setIndex))
151+ *(*unsafe.Pointer)(unsafe.Pointer(&resultdv.data)) = C.newListProperty(C.GoRef(foldr), C.intptr_t(reflectIndex), C.intptr_t(setIndex))
152 return
153 }
154
155@@ -406,8 +444,8 @@
156 }
157
158 //export hookGoValueWriteField
159-func hookGoValueWriteField(enginep, foldp unsafe.Pointer, reflectIndex, setIndex C.int, assigndv *C.DataValue) {
160- fold := ensureEngine(enginep, foldp)
161+func hookGoValueWriteField(enginep unsafe.Pointer, foldr C.GoRef, reflectIndex, setIndex C.int, assigndv *C.DataValue) {
162+ fold := ensureEngine(enginep, foldr)
163 v := reflect.ValueOf(fold.gvalue)
164 ve := v
165 for ve.Type().Kind() == reflect.Ptr {
166@@ -483,8 +521,8 @@
167 )
168
169 //export hookGoValueCallMethod
170-func hookGoValueCallMethod(enginep, foldp unsafe.Pointer, reflectIndex C.int, args *C.DataValue) {
171- fold := ensureEngine(enginep, foldp)
172+func hookGoValueCallMethod(enginep unsafe.Pointer, foldr C.GoRef, reflectIndex C.int, args *C.DataValue) {
173+ fold := ensureEngine(enginep, foldr)
174 v := reflect.ValueOf(fold.gvalue)
175
176 // TODO Must assert that v is necessarily a pointer here, but we shouldn't have to manipulate
177@@ -548,7 +586,7 @@
178 }
179
180 //export hookGoValuePaint
181-func hookGoValuePaint(enginep, foldp unsafe.Pointer, reflectIndex C.intptr_t) {
182+func hookGoValuePaint(enginep unsafe.Pointer, foldr C.GoRef, reflectIndex C.intptr_t) {
183 // Besides a convenience this is a workaround for http://golang.org/issue/8588
184 defer printPaintPanic()
185 defer atomic.StoreUintptr(&guiPaintRef, 0)
186@@ -557,7 +595,7 @@
187 // so no two paintings should be happening at the same time.
188 atomic.StoreUintptr(&guiPaintRef, cdata.Ref())
189
190- fold := ensureEngine(enginep, foldp)
191+ fold := ensureEngine(enginep, foldr)
192 if fold.init.IsValid() {
193 return
194 }
195@@ -568,8 +606,8 @@
196 method.Call([]reflect.Value{reflect.ValueOf(painter)})
197 }
198
199-func ensureEngine(enginep, foldp unsafe.Pointer) *valueFold {
200- fold := (*valueFold)(foldp)
201+func ensureEngine(enginep unsafe.Pointer, foldr C.GoRef) *valueFold {
202+ fold := getFoldFromGoRef(foldr)
203 if fold.engine != nil {
204 if fold.init.IsValid() {
205 initGoType(fold)
206@@ -637,22 +675,22 @@
207 }
208
209 //export hookListPropertyAt
210-func hookListPropertyAt(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t, index C.int) (objp unsafe.Pointer) {
211- fold := (*valueFold)(foldp)
212+func hookListPropertyAt(foldr C.GoRef, reflectIndex, setIndex C.intptr_t, index C.int) (objp unsafe.Pointer) {
213+ fold := getFoldFromGoRef(foldr)
214 slice := listSlice(fold, reflectIndex)
215 return (*slice)[int(index)].Common().addr
216 }
217
218 //export hookListPropertyCount
219-func hookListPropertyCount(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t) C.int {
220- fold := (*valueFold)(foldp)
221+func hookListPropertyCount(foldr C.GoRef, reflectIndex, setIndex C.intptr_t) C.int {
222+ fold := getFoldFromGoRef(foldr)
223 slice := listSlice(fold, reflectIndex)
224 return C.int(len(*slice))
225 }
226
227 //export hookListPropertyAppend
228-func hookListPropertyAppend(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t, objp unsafe.Pointer) {
229- fold := (*valueFold)(foldp)
230+func hookListPropertyAppend(foldr C.GoRef, reflectIndex, setIndex C.intptr_t, objp unsafe.Pointer) {
231+ fold := getFoldFromGoRef(foldr)
232 slice := listSlice(fold, reflectIndex)
233 var objdv C.DataValue
234 objdv.dataType = C.DTObject
235@@ -666,8 +704,8 @@
236 }
237
238 //export hookListPropertyClear
239-func hookListPropertyClear(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t) {
240- fold := (*valueFold)(foldp)
241+func hookListPropertyClear(foldr C.GoRef, reflectIndex, setIndex C.intptr_t) {
242+ fold := getFoldFromGoRef(foldr)
243 slice := listSlice(fold, reflectIndex)
244 newslice := (*slice)[0:0]
245 if setIndex >= 0 {
246
247=== modified file 'qml.v1/cpp/capi.cpp'
248--- qml.v1/cpp/capi.cpp 2015-06-11 10:10:38 +0000
249+++ qml.v1/cpp/capi.cpp 2016-06-17 18:52:58 +0000
250@@ -492,7 +492,7 @@
251 qobject->setParent(qparent);
252 }
253
254-error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, void *func, int argsLen)
255+error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, GoRef func, int argsLen)
256 {
257 QObject *qobject = reinterpret_cast<QObject *>(object);
258 QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
259@@ -543,17 +543,17 @@
260 return dynamic_cast<QQuickView *>(qobject) ? 1 : 0;
261 }
262
263-error *objectGoAddr(QObject_ *object, GoAddr **addr)
264+error *objectGoRef(QObject_ *object, GoRef *ref)
265 {
266 QObject *qobject = static_cast<QObject *>(object);
267 GoValue *goValue = dynamic_cast<GoValue *>(qobject);
268 if (goValue) {
269- *addr = goValue->addr;
270+ *ref = goValue->ref;
271 return 0;
272 }
273 GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
274 if (goPaintedValue) {
275- *addr = goPaintedValue->addr;
276+ *ref= goPaintedValue->ref;
277 return 0;
278 }
279 return errorf("QML object is not backed by a Go value");
280@@ -571,13 +571,13 @@
281 delete reinterpret_cast<QString *>(s);
282 }
283
284-GoValue_ *newGoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject_ *parent)
285+GoValue_ *newGoValue(GoRef ref, GoTypeInfo *typeInfo, QObject_ *parent)
286 {
287 QObject *qparent = reinterpret_cast<QObject *>(parent);
288 if (typeInfo->paint) {
289- return new GoPaintedValue(addr, typeInfo, qparent);
290+ return new GoPaintedValue(ref, typeInfo, qparent);
291 }
292- return new GoValue(addr, typeInfo, qparent);
293+ return new GoValue(ref, typeInfo, qparent);
294 }
295
296 void goValueActivate(GoValue_ *value, GoTypeInfo *typeInfo, int addrOffset)
297@@ -749,13 +749,13 @@
298 GoValue *goValue = dynamic_cast<GoValue *>(qobject);
299 if (goValue) {
300 value->dataType = DTGoAddr;
301- *(void **)(value->data) = goValue->addr;
302+ *(uintptr_t*)(value->data) = goValue->ref;
303 break;
304 }
305 GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
306 if (goPaintedValue) {
307 value->dataType = DTGoAddr;
308- *(void **)(value->data) = goPaintedValue->addr;
309+ *(uintptr_t*)(value->data) = goPaintedValue->ref;
310 break;
311 }
312 value->dataType = DTObject;
313@@ -813,28 +813,28 @@
314
315 QObject *listPropertyAt(QQmlListProperty<QObject> *list, int i)
316 {
317- return reinterpret_cast<QObject *>(hookListPropertyAt(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, i));
318+ return reinterpret_cast<QObject *>(hookListPropertyAt((uintptr_t)list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, i));
319 }
320
321 int listPropertyCount(QQmlListProperty<QObject> *list)
322 {
323- return hookListPropertyCount(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
324+ return hookListPropertyCount((uintptr_t)list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
325 }
326
327 void listPropertyAppend(QQmlListProperty<QObject> *list, QObject *obj)
328 {
329- hookListPropertyAppend(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, obj);
330+ hookListPropertyAppend((uintptr_t)list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, obj);
331 }
332
333 void listPropertyClear(QQmlListProperty<QObject> *list)
334 {
335- hookListPropertyClear(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
336+ hookListPropertyClear((uintptr_t)list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
337 }
338
339-QQmlListProperty_ *newListProperty(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex)
340+QQmlListProperty_ *newListProperty(GoRef ref, intptr_t reflectIndex, intptr_t setIndex)
341 {
342 QQmlListProperty<QObject> *list = new QQmlListProperty<QObject>();
343- list->data = addr;
344+ list->data = (void*)ref;
345 list->dummy1 = (void*)reflectIndex;
346 list->dummy2 = (void*)setIndex;
347 list->at = listPropertyAt;
348
349=== modified file 'qml.v1/cpp/capi.h'
350--- qml.v1/cpp/capi.h 2015-06-11 10:10:38 +0000
351+++ qml.v1/cpp/capi.h 2016-06-17 18:52:58 +0000
352@@ -29,7 +29,8 @@
353 typedef void QImage_;
354 typedef void GoValue_;
355 typedef void GoAddr;
356-typedef void GoTypeSpec_;
357+typedef uintptr_t GoRef;
358+typedef uintptr_t GoTypeSpec_;
359
360 typedef char error;
361 error *errorf(const char *format, ...);
362@@ -140,8 +141,8 @@
363 int objectIsComponent(QObject_ *object);
364 int objectIsWindow(QObject_ *object);
365 int objectIsView(QObject_ *object);
366-error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, void *func, int argsLen);
367-error *objectGoAddr(QObject_ *object, GoAddr **addr);
368+error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, GoRef func, int argsLen);
369+error *objectGoRef(QObject_ *object, GoRef *ref);
370
371 QQmlComponent_ *newComponent(QQmlEngine_ *engine, QObject_ *parent);
372 void componentLoadURL(QQmlComponent_ *component, const char *url, int urlLen);
373@@ -166,7 +167,7 @@
374 QString_ *newString(const char *data, int len);
375 void delString(QString_ *s);
376
377-GoValue_ *newGoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject_ *parent);
378+GoValue_ *newGoValue(GoRef ref, GoTypeInfo *typeInfo, QObject_ *parent);
379 void goValueActivate(GoValue_ *value, GoTypeInfo *typeInfo, int addrOffset);
380
381 void packDataValue(QVariant_ *var, DataValue *result);
382@@ -174,30 +175,30 @@
383
384 QVariantList_ *newVariantList(DataValue *list, int len);
385
386-QQmlListProperty_ *newListProperty(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
387+QQmlListProperty_ *newListProperty(GoRef ref, intptr_t reflectIndex, intptr_t setIndex);
388
389-int registerType(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ *spec);
390-int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ *spec);
391+int registerType(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ spec);
392+int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ spec);
393
394 void installLogHandler();
395
396 void hookIdleTimer();
397 void hookLogHandler(LogMessage *message);
398-void hookGoValueReadField(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, int getIndex, int setIndex, DataValue *result);
399-void hookGoValueWriteField(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, int setIndex, DataValue *assign);
400-void hookGoValueCallMethod(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, DataValue *result);
401-void hookGoValueDestroyed(QQmlEngine_ *engine, GoAddr *addr);
402-void hookGoValuePaint(QQmlEngine_ *engine, GoAddr *addr, intptr_t reflextIndex);
403+void hookGoValueReadField(QQmlEngine_ *engine, GoRef ref, int memberIndex, int getIndex, int setIndex, DataValue *result);
404+void hookGoValueWriteField(QQmlEngine_ *engine, GoRef ref, int memberIndex, int setIndex, DataValue *assign);
405+void hookGoValueCallMethod(QQmlEngine_ *engine, GoRef ref, int memberIndex, DataValue *result);
406+void hookGoValueDestroyed(QQmlEngine_ *engine, GoRef ref);
407+void hookGoValuePaint(QQmlEngine_ *engine, GoRef ref, intptr_t reflextIndex);
408 QImage_ *hookRequestImage(void *imageFunc, char *id, int idLen, int width, int height);
409-GoAddr *hookGoValueTypeNew(GoValue_ *value, GoTypeSpec_ *spec);
410+GoRef hookGoValueTypeNew(GoValue_ *value, GoTypeSpec_ spec);
411 void hookWindowHidden(QObject_ *addr);
412-void hookSignalCall(QQmlEngine_ *engine, void *func, DataValue *params);
413-void hookSignalDisconnect(void *func);
414+void hookSignalCall(QQmlEngine_ *engine, GoRef func, DataValue *params);
415+void hookSignalDisconnect(GoRef func);
416 void hookPanic(char *message);
417-int hookListPropertyCount(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
418-QObject_ *hookListPropertyAt(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex, int i);
419-void hookListPropertyAppend(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex, QObject_ *obj);
420-void hookListPropertyClear(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
421+int hookListPropertyCount(GoRef ref, intptr_t reflectIndex, intptr_t setIndex);
422+QObject_ *hookListPropertyAt(GoRef ref, intptr_t reflectIndex, intptr_t setIndex, int i);
423+void hookListPropertyAppend(GoRef ref, intptr_t reflectIndex, intptr_t setIndex, QObject_ *obj);
424+void hookListPropertyClear(GoRef ref, intptr_t reflectIndex, intptr_t setIndex);
425
426 void registerResourceData(int version, char *tree, char *name, char *data);
427 void unregisterResourceData(int version, char *tree, char *name, char *data);
428
429=== modified file 'qml.v1/cpp/connector.h'
430--- qml.v1/cpp/connector.h 2015-06-11 10:10:38 +0000
431+++ qml.v1/cpp/connector.h 2016-06-17 18:52:58 +0000
432@@ -11,7 +11,7 @@
433
434 public:
435
436- Connector(QObject *sender, QMetaMethod method, QQmlEngine *engine, void *func, int argsLen)
437+ Connector(QObject *sender, QMetaMethod method, QQmlEngine *engine, GoRef func, int argsLen)
438 : QObject(sender), engine(engine), method(method), func(func), argsLen(argsLen) {};
439
440 virtual ~Connector();
441@@ -27,7 +27,7 @@
442
443 QQmlEngine *engine;
444 QMetaMethod method;
445- void *func;
446+ GoRef func;
447 int argsLen;
448 };
449
450
451=== modified file 'qml.v1/cpp/govalue.cpp'
452--- qml.v1/cpp/govalue.cpp 2015-06-11 10:10:38 +0000
453+++ qml.v1/cpp/govalue.cpp 2016-06-17 18:52:58 +0000
454@@ -13,7 +13,7 @@
455 class GoValueMetaObject : public QAbstractDynamicMetaObject
456 {
457 public:
458- GoValueMetaObject(QObject* value, GoAddr *addr, GoTypeInfo *typeInfo);
459+ GoValueMetaObject(QObject* value, GoRef ref, GoTypeInfo *typeInfo);
460
461 void activatePropIndex(int propIndex);
462
463@@ -22,12 +22,12 @@
464
465 private:
466 QObject *value;
467- GoAddr *addr;
468+ GoRef ref;
469 GoTypeInfo *typeInfo;
470 };
471
472-GoValueMetaObject::GoValueMetaObject(QObject *value, GoAddr *addr, GoTypeInfo *typeInfo)
473- : value(value), addr(addr), typeInfo(typeInfo)
474+GoValueMetaObject::GoValueMetaObject(QObject *value, GoRef ref, GoTypeInfo *typeInfo)
475+ : value(value), ref(ref), typeInfo(typeInfo)
476 {
477 //d->parent = static_cast<QAbstractDynamicMetaObject *>(priv->metaObject);
478 *static_cast<QMetaObject *>(this) = *metaObjectFor(typeInfo);
479@@ -53,7 +53,7 @@
480 if (memberInfo->metaIndex == idx) {
481 if (c == QMetaObject::ReadProperty) {
482 DataValue result;
483- hookGoValueReadField(qmlEngine(value), addr, memberInfo->reflectIndex, memberInfo->reflectGetIndex, memberInfo->reflectSetIndex, &result);
484+ hookGoValueReadField(qmlEngine(value), ref, memberInfo->reflectIndex, memberInfo->reflectGetIndex, memberInfo->reflectSetIndex, &result);
485 if (memberInfo->memberType == DTListProperty) {
486 if (result.dataType != DTListProperty) {
487 panicf("reading DTListProperty field returned non-DTListProperty result");
488@@ -71,7 +71,7 @@
489 DataValue assign;
490 QVariant *in = reinterpret_cast<QVariant *>(a[0]);
491 packDataValue(in, &assign);
492- hookGoValueWriteField(qmlEngine(value), addr, memberInfo->reflectIndex, memberInfo->reflectSetIndex, &assign);
493+ hookGoValueWriteField(qmlEngine(value), ref, memberInfo->reflectIndex, memberInfo->reflectSetIndex, &assign);
494 activate(value, methodOffset() + (idx - propOffset), 0);
495 }
496 return -1;
497@@ -95,7 +95,7 @@
498 for (int i = 1; i < memberInfo->numIn+1; i++) {
499 packDataValue(reinterpret_cast<QVariant *>(a[i]), &args[i]);
500 }
501- hookGoValueCallMethod(qmlEngine(value), addr, memberInfo->reflectIndex, args);
502+ hookGoValueCallMethod(qmlEngine(value), ref, memberInfo->reflectIndex, args);
503 if (memberInfo->numOut > 0) {
504 unpackDataValue(&args[0], reinterpret_cast<QVariant *>(a[0]));
505 }
506@@ -121,16 +121,16 @@
507 activate(value, methodOffset() + relativeIndex, 0);
508 }
509
510-GoValue::GoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent)
511- : addr(addr), typeInfo(typeInfo)
512+GoValue::GoValue(GoRef ref, GoTypeInfo *typeInfo, QObject *parent)
513+ : ref(ref), typeInfo(typeInfo)
514 {
515- valueMeta = new GoValueMetaObject(this, addr, typeInfo);
516+ valueMeta = new GoValueMetaObject(this, ref, typeInfo);
517 setParent(parent);
518 }
519
520 GoValue::~GoValue()
521 {
522- hookGoValueDestroyed(qmlEngine(this), addr);
523+ hookGoValueDestroyed(qmlEngine(this), ref);
524 }
525
526 void GoValue::activate(int propIndex)
527@@ -138,10 +138,10 @@
528 valueMeta->activatePropIndex(propIndex);
529 }
530
531-GoPaintedValue::GoPaintedValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent)
532- : addr(addr), typeInfo(typeInfo)
533+GoPaintedValue::GoPaintedValue(GoRef ref, GoTypeInfo *typeInfo, QObject *parent)
534+ : ref(ref), typeInfo(typeInfo)
535 {
536- valueMeta = new GoValueMetaObject(this, addr, typeInfo);
537+ valueMeta = new GoValueMetaObject(this, ref, typeInfo);
538 setParent(parent);
539
540 QQuickItem::setFlag(QQuickItem::ItemHasContents, true);
541@@ -150,7 +150,7 @@
542
543 GoPaintedValue::~GoPaintedValue()
544 {
545- hookGoValueDestroyed(qmlEngine(this), addr);
546+ hookGoValueDestroyed(qmlEngine(this), ref);
547 }
548
549 void GoPaintedValue::activate(int propIndex)
550@@ -161,7 +161,7 @@
551 void GoPaintedValue::paint(QPainter *painter)
552 {
553 painter->beginNativePainting();
554- hookGoValuePaint(qmlEngine(this), addr, typeInfo->paint->reflectIndex);
555+ hookGoValuePaint(qmlEngine(this), ref, typeInfo->paint->reflectIndex);
556 painter->endNativePainting();
557 }
558
559
560=== modified file 'qml.v1/cpp/govalue.h'
561--- qml.v1/cpp/govalue.h 2015-06-11 10:10:38 +0000
562+++ qml.v1/cpp/govalue.h 2016-06-17 18:52:58 +0000
563@@ -20,10 +20,10 @@
564 Q_OBJECT
565
566 public:
567- GoAddr *addr;
568+ GoRef ref;
569 GoTypeInfo *typeInfo;
570
571- GoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent);
572+ GoValue(GoRef ref, GoTypeInfo *typeInfo, QObject *parent);
573 virtual ~GoValue();
574
575 void activate(int propIndex);
576@@ -37,10 +37,10 @@
577 Q_OBJECT
578
579 public:
580- GoAddr *addr;
581+ GoRef ref;
582 GoTypeInfo *typeInfo;
583
584- GoPaintedValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent);
585+ GoPaintedValue(GoRef ref, GoTypeInfo *typeInfo, QObject *parent);
586 virtual ~GoPaintedValue();
587
588 void activate(int propIndex);
589
590=== modified file 'qml.v1/cpp/govaluetype.cpp'
591--- qml.v1/cpp/govaluetype.cpp 2015-06-11 10:10:38 +0000
592+++ qml.v1/cpp/govaluetype.cpp 2016-06-17 18:52:58 +0000
593@@ -3,12 +3,12 @@
594 #define DEFINE_GOVALUETYPE(N) \
595 template<> QMetaObject GoValueType<N>::staticMetaObject = QMetaObject(); \
596 template<> GoTypeInfo *GoValueType<N>::typeInfo = 0; \
597- template<> GoTypeSpec_ *GoValueType<N>::typeSpec = 0;
598+ template<> GoTypeSpec_ GoValueType<N>::typeSpec = 0;
599
600 #define DEFINE_GOPAINTEDVALUETYPE(N) \
601 template<> QMetaObject GoPaintedValueType<N>::staticMetaObject = QMetaObject(); \
602 template<> GoTypeInfo *GoPaintedValueType<N>::typeInfo = 0; \
603- template<> GoTypeSpec_ *GoPaintedValueType<N>::typeSpec = 0;
604+ template<> GoTypeSpec_ GoPaintedValueType<N>::typeSpec = 0;
605
606 DEFINE_GOVALUETYPE(1)
607 DEFINE_GOVALUETYPE(2)
608@@ -76,7 +76,7 @@
609 static int goPaintedValueTypeN = 0;
610
611 template<int N>
612-int registerSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec) {
613+int registerSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ spec) {
614 GoValueType<N>::init(info, spec);
615 return qmlRegisterSingletonType< GoValueType<N> >(location, major, minor, name, [](QQmlEngine *qmlEngine, QJSEngine *jsEngine) -> QObject* {
616 QObject *singleton = new GoValueType<N>();
617@@ -86,7 +86,7 @@
618 }
619
620 template<int N>
621-int registerPaintedSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec) {
622+int registerPaintedSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ spec) {
623 GoPaintedValueType<N>::init(info, spec);
624 return qmlRegisterSingletonType< GoPaintedValueType<N> >(location, major, minor, name, [](QQmlEngine *qmlEngine, QJSEngine *jsEngine) -> QObject* {
625 QObject *singleton = new GoPaintedValueType<N>();
626@@ -100,7 +100,7 @@
627 #define GOPAINTEDVALUETYPE_CASE_SINGLETON(N) \
628 case N: return registerPaintedSingletonN<N>(location, major, minor, name, info, spec);
629
630-int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec)
631+int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ spec)
632 {
633 if (!info->paint) {
634 switch (++goValueTypeN) {
635@@ -178,7 +178,7 @@
636 #define GOPAINTEDVALUETYPE_CASE(N) \
637 case N: GoPaintedValueType<N>::init(info, spec); return qmlRegisterType< GoPaintedValueType<N> >(location, major, minor, name);
638
639-int registerType(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec)
640+int registerType(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ spec)
641 {
642 if (!info->paint) {
643 switch (++goValueTypeN) {
644
645=== modified file 'qml.v1/cpp/govaluetype.h'
646--- qml.v1/cpp/govaluetype.h 2015-06-11 10:10:38 +0000
647+++ qml.v1/cpp/govaluetype.h 2016-06-17 18:52:58 +0000
648@@ -11,14 +11,14 @@
649 GoValueType()
650 : GoValue(hookGoValueTypeNew(this, typeSpec), typeInfo, 0) {};
651
652- static void init(GoTypeInfo *info, GoTypeSpec_ *spec)
653+ static void init(GoTypeInfo *info, GoTypeSpec_ spec)
654 {
655 typeInfo = info;
656 typeSpec = spec;
657 static_cast<QMetaObject &>(staticMetaObject) = *metaObjectFor(typeInfo);
658 };
659
660- static GoTypeSpec_ *typeSpec;
661+ static GoTypeSpec_ typeSpec;
662 static GoTypeInfo *typeInfo;
663 static QMetaObject staticMetaObject;
664 };
665@@ -31,14 +31,14 @@
666 GoPaintedValueType()
667 : GoPaintedValue(hookGoValueTypeNew(this, typeSpec), typeInfo, 0) {};
668
669- static void init(GoTypeInfo *info, GoTypeSpec_ *spec)
670+ static void init(GoTypeInfo *info, GoTypeSpec_ spec)
671 {
672 typeInfo = info;
673 typeSpec = spec;
674 static_cast<QMetaObject &>(staticMetaObject) = *metaObjectFor(typeInfo);
675 };
676
677- static GoTypeSpec_ *typeSpec;
678+ static GoTypeSpec_ typeSpec;
679 static GoTypeInfo *typeInfo;
680 static QMetaObject staticMetaObject;
681 };
682
683=== modified file 'qml.v1/datatype.go'
684--- qml.v1/datatype.go 2015-06-11 10:10:38 +0000
685+++ qml.v1/datatype.go 2016-06-17 18:52:58 +0000
686@@ -155,8 +155,7 @@
687 case C.DTGoAddr:
688 // ObjectByName also does this fold conversion, to have access
689 // to the cvalue. Perhaps the fold should be returned.
690- fold := (*(**valueFold)(datap))
691- ensureEngine(engine.addr, unsafe.Pointer(fold))
692+ fold := ensureEngine(engine.addr, C.GoRef(uintptr(datap)))
693 return fold.gvalue
694 case C.DTInvalid:
695 return nil
696
697=== modified file 'qml.v1/qml.go'
698--- qml.v1/qml.go 2015-06-11 10:25:43 +0000
699+++ qml.v1/qml.go 2016-06-17 18:52:58 +0000
700@@ -484,8 +484,9 @@
701 var result interface{}
702 var cerr *C.error
703 RunMain(func() {
704- var fold *valueFold
705- if cerr = C.objectGoAddr(obj.addr, (*unsafe.Pointer)(unsafe.Pointer(&fold))); cerr == nil {
706+ var foldr C.GoRef
707+ if cerr = C.objectGoRef(obj.addr, &foldr); cerr == nil {
708+ fold := getFoldFromGoRef(foldr)
709 result = fold.gvalue
710 }
711 })
712@@ -765,7 +766,7 @@
713 })
714 }
715
716-var connectedFunction = make(map[*interface{}]bool)
717+var connectedFunction = make(map[C.GoRef]interface{})
718
719 // On connects the named signal from obj with the provided function, so that
720 // when obj next emits that signal, the function is called with the parameters
721@@ -799,9 +800,10 @@
722 csignal, csignallen := unsafeStringData(signal)
723 var cerr *C.error
724 RunMain(func() {
725- cerr = C.objectConnect(obj.addr, csignal, csignallen, obj.engine.addr, unsafe.Pointer(&function), C.int(funcv.Type().NumIn()))
726+ funcr := C.GoRef(uintptr(unsafe.Pointer(&function)))
727+ cerr = C.objectConnect(obj.addr, csignal, csignallen, obj.engine.addr, funcr, C.int(funcv.Type().NumIn()))
728 if cerr == nil {
729- connectedFunction[&function] = true
730+ connectedFunction[funcr] = function
731 stats.connectionsAlive(+1)
732 }
733 })
734@@ -809,9 +811,9 @@
735 }
736
737 //export hookSignalDisconnect
738-func hookSignalDisconnect(funcp unsafe.Pointer) {
739+func hookSignalDisconnect(funcr C.GoRef) {
740 before := len(connectedFunction)
741- delete(connectedFunction, (*interface{})(funcp))
742+ delete(connectedFunction, funcr)
743 if before == len(connectedFunction) {
744 panic("disconnecting unknown signal function")
745 }
746@@ -819,12 +821,18 @@
747 }
748
749 //export hookSignalCall
750-func hookSignalCall(enginep unsafe.Pointer, funcp unsafe.Pointer, args *C.DataValue) {
751+func hookSignalCall(enginep unsafe.Pointer, funcr C.GoRef, args *C.DataValue) {
752 engine := engines[enginep]
753 if engine == nil {
754 panic("signal called after engine was destroyed")
755 }
756- funcv := reflect.ValueOf(*(*interface{})(funcp))
757+
758+ function := connectedFunction[funcr]
759+ if function == nil {
760+ panic("signal called on disconnected function")
761+ }
762+
763+ funcv := reflect.ValueOf(&function)
764 funct := funcv.Type()
765 numIn := funct.NumIn()
766 var params [C.MaxParams]reflect.Value
767@@ -990,7 +998,7 @@
768 private struct{} // Force use of fields by name.
769 }
770
771-var types []*TypeSpec
772+var types = make(map[C.GoTypeSpec_]*TypeSpec)
773
774 // RegisterTypes registers the provided list of type specifications for use
775 // by QML code. To access the registered types, they must be imported from the
776@@ -1046,10 +1054,11 @@
777 cloc := C.CString(location)
778 cname := C.CString(localSpec.Name)
779 cres := C.int(0)
780+ localSpecRef := C.GoTypeSpec_(uintptr(unsafe.Pointer(&localSpec)))
781 if localSpec.Singleton {
782- cres = C.registerSingleton(cloc, C.int(major), C.int(minor), cname, customType, unsafe.Pointer(&localSpec))
783+ cres = C.registerSingleton(cloc, C.int(major), C.int(minor), cname, customType, localSpecRef)
784 } else {
785- cres = C.registerType(cloc, C.int(major), C.int(minor), cname, customType, unsafe.Pointer(&localSpec))
786+ cres = C.registerType(cloc, C.int(major), C.int(minor), cname, customType, localSpecRef)
787 }
788 // It doesn't look like it keeps references to these, but it's undocumented and unclear.
789 C.free(unsafe.Pointer(cloc))
790@@ -1057,7 +1066,7 @@
791 if cres == -1 {
792 err = fmt.Errorf("QML engine failed to register type; invalid type location or name?")
793 } else {
794- types = append(types, &localSpec)
795+ types[localSpecRef] = &localSpec
796 }
797 })
798

Subscribers

People subscribed via source and target branches