gjs r118 - in trunk: gi test/js
- From: otaylor svn gnome org
- To: svn-commits-list gnome org
- Subject: gjs r118 - in trunk: gi test/js
- Date: Wed, 19 Nov 2008 22:31:12 +0000 (UTC)
Author: otaylor
Date: Wed Nov 19 22:31:12 2008
New Revision: 118
URL: http://svn.gnome.org/viewvc/gjs?rev=118&view=rev
Log:
Support simple structures not registered as boxed
Allow creating a "Boxed" object for a simple structure that is not
registered as a GBoxed.
Renames:
gjs_g_boxed_from_boxed() => gjs_c_struct_from_boxed()
gjs_boxed_from_g_boxed() => gjs_boxed_from_c_struct()
gjs_g_boxed_from_union() => gjs_c_struct_from_union()
gjs_union_from_g_boxed() => gjs_union_from_c_struct()
Change from passing GType to _from_g_boxed() to passing
GI[Struct|Union]Info to _from_c_struct()
gi/boxed.c: Allow for g_registered_type_info_get_g_type() returning
G_TYPE_NONE.
gi/union.c: Add check (for now) that the union type is registered as
a GBoxed before registering the JS class.
gi/arg.c: Check whether the GIBaseInfo STRUCT/BOXED/UNION before
getting the GType and making a decision based on that.
test/js/testEverythingEncapsulated.js: Add tests for simple structures
https://bugzilla.gnome.org/show_bug.cgi?id=560808
Modified:
trunk/gi/arg.c
trunk/gi/boxed.c
trunk/gi/boxed.h
trunk/gi/function.c
trunk/gi/union.c
trunk/gi/union.h
trunk/gi/value.c
trunk/test/js/testEverythingEncapsulated.js
Modified: trunk/gi/arg.c
==============================================================================
--- trunk/gi/arg.c (original)
+++ trunk/gi/arg.c Wed Nov 19 22:31:12 2008
@@ -408,15 +408,19 @@
nullable_type = TRUE;
{
GIBaseInfo* symbol_info;
+ GIInfoType symbol_type;
GType gtype;
symbol_info = g_type_info_get_interface(type_info);
g_assert(symbol_info != NULL);
+ symbol_type = g_base_info_get_type(symbol_info);
+
gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*)symbol_info);
- gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
- "gtype of SYMBOL is %s", g_type_name(gtype));
+ if (gtype != G_TYPE_NONE)
+ gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
+ "gtype of SYMBOL is %s", g_type_name(gtype));
if (gtype == G_TYPE_VALUE) {
GValue *gvalue;
@@ -433,53 +437,65 @@
} else if (JSVAL_IS_NULL(value)) {
arg->v_pointer = NULL;
} else if (JSVAL_IS_OBJECT(value)) {
- if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) {
- arg->v_pointer = gjs_g_object_from_object(context,
- JSVAL_TO_OBJECT(value));
- if (arg->v_pointer != NULL) {
- if (!g_type_is_a(G_TYPE_FROM_INSTANCE(arg->v_pointer),
- gtype)) {
+ /* Handle Struct/Union first since we don't necessarily need a GType for them */
+ if (symbol_type == GI_INFO_TYPE_STRUCT || symbol_type == GI_INFO_TYPE_BOXED) {
+ arg->v_pointer = gjs_c_struct_from_boxed(context,
+ JSVAL_TO_OBJECT(value));
+
+ } else if (symbol_type == GI_INFO_TYPE_UNION) {
+ arg->v_pointer = gjs_c_union_from_union(context,
+ JSVAL_TO_OBJECT(value));
+
+ } else if (gtype != G_TYPE_NONE) {
+
+ if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) {
+ arg->v_pointer = gjs_g_object_from_object(context,
+ JSVAL_TO_OBJECT(value));
+ if (arg->v_pointer != NULL) {
+ if (!g_type_is_a(G_TYPE_FROM_INSTANCE(arg->v_pointer),
+ gtype)) {
+ gjs_throw(context,
+ "Expected type '%s' but got '%s'",
+ g_type_name(gtype),
+ g_type_name(G_TYPE_FROM_INSTANCE(arg->v_pointer)));
+ arg->v_pointer = NULL;
+ wrong = TRUE;
+ }
+ }
+ } else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
+ if (g_type_is_a(gtype, G_TYPE_CLOSURE)) {
+ arg->v_pointer = gjs_closure_new_marshaled(context,
+ JSVAL_TO_OBJECT(value),
+ "boxed");
+ } else {
+ /* Should have been caught above as STRUCT/BOXED/UNION */
gjs_throw(context,
- "Expected type '%s' but got '%s'",
+ "Boxed type %s registered for unexpected symbol_type %d",
g_type_name(gtype),
- g_type_name(G_TYPE_FROM_INSTANCE(arg->v_pointer)));
- arg->v_pointer = NULL;
- wrong = TRUE;
+ symbol_type);
}
- }
- } else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
- if (g_type_is_a(gtype, G_TYPE_CLOSURE)) {
- arg->v_pointer = gjs_closure_new_marshaled(context,
- JSVAL_TO_OBJECT(value),
- "boxed");
- } else if (g_base_info_get_type(symbol_info) == GI_INFO_TYPE_UNION) {
- arg->v_pointer = gjs_g_boxed_from_union(context,
- JSVAL_TO_OBJECT(value));
} else {
- arg->v_pointer = gjs_g_boxed_from_boxed(context,
- JSVAL_TO_OBJECT(value));
+ gjs_throw(context, "Unhandled GType %s unpacking SYMBOL GArgument from Object",
+ g_type_name(gtype));
}
- } else {
- gjs_throw(context, "Unhandled GType %s unpacking SYMBOL GArgument from Object",
- g_type_name(gtype));
}
if (arg->v_pointer == NULL) {
gjs_debug(GJS_DEBUG_GFUNCTION,
- "conversion of JSObject %p type %s to gtype %s failed",
+ "conversion of JSObject %p type %s to type %s failed",
JSVAL_TO_OBJECT(value),
JS_GetTypeName(context,
JS_TypeOfValue(context, value)),
- g_type_name(gtype));
+ g_base_info_get_name ((GIBaseInfo *)symbol_info));
- /* bis_js_throw should have been called already */
+ /* gjs_throw should have been called already */
wrong = TRUE;
}
} else if (JSVAL_IS_NUMBER(value)) {
nullable_type = FALSE;
- if (g_base_info_get_type(symbol_info) == GI_INFO_TYPE_ENUM) {
+ if (symbol_type == GI_INFO_TYPE_ENUM) {
if (!JS_ValueToInt32(context, value, &arg->v_int)) {
wrong = TRUE;
} else if (!_gjs_enum_value_is_valid(context, (GIEnumInfo *)symbol_info, arg->v_int)) {
@@ -838,12 +854,15 @@
} else {
jsval value;
GIBaseInfo* symbol_info;
+ GIInfoType symbol_type;
GType gtype;
symbol_info = g_type_info_get_interface(type_info);
g_assert(symbol_info != NULL);
- if (g_base_info_get_type(symbol_info) == GI_INFO_TYPE_UNRESOLVED) {
+ symbol_type = g_base_info_get_type(symbol_info);
+
+ if (symbol_type == GI_INFO_TYPE_UNRESOLVED) {
gjs_throw(context,
"Unable to resolve arg type '%s'",
g_base_info_get_name(symbol_info));
@@ -851,13 +870,30 @@
return JS_FALSE;
}
+ value = JSVAL_VOID;
+
+ /* Handle Struct/Union first since we don't necessarily need a GType for them */
+ if (symbol_type == GI_INFO_TYPE_STRUCT || symbol_type == GI_INFO_TYPE_BOXED) {
+ JSObject *obj;
+ obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)symbol_info, arg->v_pointer);
+ if (obj)
+ value = OBJECT_TO_JSVAL(obj);
+
+ goto out;
+ } else if (symbol_type == GI_INFO_TYPE_UNION) {
+ JSObject *obj;
+ obj = gjs_union_from_c_union(context, (GIUnionInfo *)symbol_info, arg->v_pointer);
+ if (obj)
+ value = OBJECT_TO_JSVAL(obj);
+
+ goto out;
+ }
+
gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*)symbol_info);
gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
"gtype of SYMBOL is %s", g_type_name(gtype));
- value = JSVAL_VOID;
-
if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) {
JSObject *obj;
obj = gjs_object_from_g_object(context, G_OBJECT(arg->v_pointer));
@@ -869,15 +905,13 @@
return JS_FALSE;
}
} else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
- JSObject *obj;
- if (g_base_info_get_type(symbol_info) == GI_INFO_TYPE_UNION) {
- obj = gjs_union_from_g_boxed(context, gtype, arg->v_pointer);
- } else {
- obj = gjs_boxed_from_g_boxed(context, gtype, arg->v_pointer);
- }
- if (obj)
- value = OBJECT_TO_JSVAL(obj);
- } else if (g_base_info_get_type(symbol_info) == GI_INFO_TYPE_ENUM) {
+ /* Should have been caught above as STRUCT/BOXED/UNION */
+ gjs_throw(context,
+ "Boxed type %s registered for unexpected symbol_type %d",
+ g_type_name(gtype),
+ symbol_type);
+ return JS_FALSE;
+ } else if (symbol_type == GI_INFO_TYPE_ENUM) {
if (_gjs_enum_value_is_valid(context, (GIEnumInfo *)symbol_info, arg->v_int))
value = INT_TO_JSVAL(arg->v_int);
} else if (g_type_is_a(gtype, G_TYPE_FLAGS)) {
@@ -894,6 +928,7 @@
g_type_name(gtype));
}
+ out:
g_base_info_unref( (GIBaseInfo*) symbol_info);
if (JSVAL_IS_VOID(value))
Modified: trunk/gi/boxed.c
==============================================================================
--- trunk/gi/boxed.c (original)
+++ trunk/gi/boxed.c Wed Nov 19 22:31:12 2008
@@ -184,69 +184,85 @@
}
static JSBool
+boxed_new_direct(JSContext *context,
+ JSObject *obj, /* "this" for constructor */
+ Boxed *priv)
+{
+ g_assert(priv->can_allocate_directly);
+
+ priv->gboxed = g_slice_alloc0(g_struct_info_get_size (priv->info));
+ priv->allocated_directly = TRUE;
+
+ gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
+ "JSObject created by directly allocating %s",
+ g_base_info_get_name ((GBaseInfo *)priv->info));
+
+ return JS_TRUE;
+}
+
+static JSBool
boxed_new(JSContext *context,
JSObject *obj, /* "this" for constructor */
Boxed *priv)
{
+ GType gtype;
int n_methods;
int i;
- /* Find a zero-args constructor and call it */
+ gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
- n_methods = g_struct_info_get_n_methods(priv->info);
-
- for (i = 0; i < n_methods; ++i) {
- GIFunctionInfo *func_info;
- GIFunctionInfoFlags flags;
-
- func_info = g_struct_info_get_method(priv->info, i);
+ if (gtype != G_TYPE_NONE) {
+ /* If the structure is registered as a boxed, we can create a new instance by
+ * looking for a zero-args constructor and calling it; constructors don't
+ * really make sense for non-boxed types, since there is no memory management
+ * for the return value; those are handled below along with simple boxed
+ * structures without constructor.
+ */
+ n_methods = g_struct_info_get_n_methods(priv->info);
- flags = g_function_info_get_flags(func_info);
- if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 &&
- g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) {
+ for (i = 0; i < n_methods; ++i) {
+ GIFunctionInfo *func_info;
+ GIFunctionInfoFlags flags;
- jsval rval;
- GType gtype;
- void *gboxed;
+ func_info = g_struct_info_get_method(priv->info, i);
- rval = JSVAL_NULL;
- gjs_invoke_c_function(context, func_info, obj,
- 0, NULL, &rval);
+ flags = g_function_info_get_flags(func_info);
+ if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 &&
+ g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) {
- g_base_info_unref((GIBaseInfo*) func_info);
+ jsval rval;
+ void *gboxed;
- if (JSVAL_IS_NULL(rval))
- return JS_FALSE;
+ rval = JSVAL_NULL;
+ gjs_invoke_c_function(context, func_info, obj,
+ 0, NULL, &rval);
- /* We are somewhat wasteful here; invoke_c_function() above
- * creates a JSObject wrapper for the boxed that we immediately
- * discard.
- */
- gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
- gboxed = gjs_g_boxed_from_boxed(context, JSVAL_TO_OBJECT(rval));
- priv->gboxed = g_boxed_copy (gtype, gboxed);
-
- gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
- "JSObject created with boxed instance %p type %s",
- priv->gboxed, g_type_name(gtype));
+ g_base_info_unref((GIBaseInfo*) func_info);
- return JS_TRUE;
- }
+ if (JSVAL_IS_NULL(rval))
+ return JS_FALSE;
- g_base_info_unref((GIBaseInfo*) func_info);
- }
+ /* We are somewhat wasteful here; invoke_c_function() above
+ * creates a JSObject wrapper for the boxed that we immediately
+ * discard.
+ */
+ gboxed = gjs_c_struct_from_boxed(context, JSVAL_TO_OBJECT(rval));
+ priv->gboxed = g_boxed_copy (gtype, gboxed);
- if (priv->can_allocate_directly) {
- priv->gboxed = g_slice_alloc0(g_struct_info_get_size (priv->info));
- priv->allocated_directly = TRUE;
+ gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
+ "JSObject created with boxed instance %p type %s",
+ priv->gboxed, g_type_name(gtype));
- gjs_debug_lifecycle(GJS_DEBUG_GBOXED,
- "JSObject created by directly allocating %s",
- g_base_info_get_name ((GBaseInfo *)priv->info));
+ return JS_TRUE;
+ }
- return JS_TRUE;
+ g_base_info_unref((GIBaseInfo*) func_info);
+ }
}
+ if (priv->can_allocate_directly)
+ return boxed_new_direct(context, obj, priv);
+
gjs_throw(context, "Unable to construct boxed type %s since it has no zero-args <constructor>, can only wrap an existing one",
g_base_info_get_name((GIBaseInfo*) priv->info));
@@ -503,8 +519,25 @@
} else {
GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
- priv->gboxed = g_boxed_copy(gtype, unthreadsafe_template_for_constructor.gboxed);
+ if (gtype != G_TYPE_NONE) {
+ priv->gboxed = g_boxed_copy(gtype,
+ unthreadsafe_template_for_constructor.gboxed);
+ } else if (priv->can_allocate_directly) {
+ if (!boxed_new_direct(context, obj, priv))
+ return JS_FALSE;
+
+ memcpy(priv->gboxed,
+ unthreadsafe_template_for_constructor.gboxed,
+ g_struct_info_get_size (priv->info));
+ } else {
+ gjs_throw(context,
+ "Can't create a Javascript object for %s; no way to copy",
+ g_base_info_get_name( (GIBaseInfo*) priv->info));
+ }
+
unthreadsafe_template_for_constructor.gboxed = NULL;
+
+ return priv->gboxed != NULL;
}
}
@@ -524,11 +557,14 @@
return; /* wrong class? */
if (priv->gboxed) {
- if (priv->allocated_directly)
+ if (priv->allocated_directly) {
g_slice_free1(g_struct_info_get_size (priv->info), priv->gboxed);
- else
- g_boxed_free(g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info),
- priv->gboxed);
+ } else {
+ GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
+ g_assert(gtype != G_TYPE_NONE);
+
+ g_boxed_free(gtype, priv->gboxed);
+ }
priv->gboxed = NULL;
}
@@ -581,7 +617,6 @@
info = g_type_info_get_interface (type_info);
if (!(g_base_info_get_type (info) == GI_INFO_TYPE_STRUCT || g_base_info_get_type (info) == GI_INFO_TYPE_BOXED) ||
- g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*)info) == G_TYPE_NONE ||
!struct_is_simple ((GIStructInfo *)info)) {
gjs_throw(context, "Reading field %s.%s is not supported",
g_base_info_get_name ((GIBaseInfo *)parent_priv->info),
@@ -693,7 +728,6 @@
info = g_type_info_get_interface (type_info);
if (!(g_base_info_get_type (info) == GI_INFO_TYPE_STRUCT || g_base_info_get_type (info) == GI_INFO_TYPE_BOXED) ||
- g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*)info) == G_TYPE_NONE ||
!struct_is_simple ((GIStructInfo *)info)) {
gjs_throw(context, "Writing field %s.%s is not supported",
g_base_info_get_name ((GIBaseInfo *)parent_priv->info),
@@ -1016,8 +1050,7 @@
switch (g_base_info_get_type (interface)) {
case GI_INFO_TYPE_BOXED:
case GI_INFO_TYPE_STRUCT:
- if (g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*)info) == G_TYPE_NONE ||
- !struct_is_simple ((GIStructInfo *)interface))
+ if (!struct_is_simple ((GIStructInfo *)interface))
is_simple = FALSE;
break;
case GI_INFO_TYPE_UNION:
@@ -1170,58 +1203,33 @@
}
JSObject*
-gjs_boxed_from_g_boxed(JSContext *context,
- GType gtype,
- void *gboxed)
+gjs_boxed_from_c_struct(JSContext *context,
+ GIStructInfo *info,
+ void *gboxed)
{
- JSObject *obj;
JSObject *proto;
- GIBaseInfo *info;
if (gboxed == NULL)
return NULL;
gjs_debug_marshal(GJS_DEBUG_GBOXED,
- "Wrapping boxed %s %p with JSObject",
- g_type_name(gtype), gboxed);
-
- info = g_irepository_find_by_gtype(g_irepository_get_default(),
- gtype);
-
- if (info == NULL) {
- gjs_throw(context,
- "Unknown boxed type %s",
- g_type_name(gtype));
- return NULL;
- }
-
- if (g_base_info_get_type( (GIBaseInfo*) info) != GI_INFO_TYPE_BOXED &&
- g_base_info_get_type( (GIBaseInfo*) info) != GI_INFO_TYPE_STRUCT) {
- gjs_throw(context,
- "GType %s doesn't map to boxed in g-i?",
- g_base_info_get_name( (GIBaseInfo*) info));
- g_base_info_unref( (GIBaseInfo*) info);
- return NULL;
- }
+ "Wrapping struct %s %p with JSObject",
+ g_base_info_get_name((GBaseInfo *)info), gboxed);
- proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) info);
+ proto = gjs_lookup_boxed_prototype(context, info);
/* can't come up with a better approach... */
- unthreadsafe_template_for_constructor.info = (GIBoxedInfo*) info;
+ unthreadsafe_template_for_constructor.info = info;
unthreadsafe_template_for_constructor.gboxed = gboxed;
unthreadsafe_template_for_constructor.parent_jsval = JSVAL_NULL;
- obj = gjs_construct_object_dynamic(context, proto,
- 0, NULL);
-
- g_base_info_unref( (GIBaseInfo*) info);
-
- return obj;
+ return gjs_construct_object_dynamic(context, proto,
+ 0, NULL);
}
void*
-gjs_g_boxed_from_boxed(JSContext *context,
- JSObject *obj)
+gjs_c_struct_from_boxed(JSContext *context,
+ JSObject *obj)
{
Boxed *priv;
Modified: trunk/gi/boxed.h
==============================================================================
--- trunk/gi/boxed.h (original)
+++ trunk/gi/boxed.h Wed Nov 19 22:31:12 2008
@@ -46,10 +46,10 @@
GIBoxedInfo *info);
JSClass* gjs_lookup_boxed_class (JSContext *context,
GIBoxedInfo *info);
-void* gjs_g_boxed_from_boxed (JSContext *context,
+void* gjs_c_struct_from_boxed (JSContext *context,
JSObject *obj);
-JSObject* gjs_boxed_from_g_boxed (JSContext *context,
- GType gtype,
+JSObject* gjs_boxed_from_c_struct (JSContext *context,
+ GIStructInfo *info,
void *gboxed);
G_END_DECLS
Modified: trunk/gi/function.c
==============================================================================
--- trunk/gi/function.c (original)
+++ trunk/gi/function.c Wed Nov 19 22:31:12 2008
@@ -173,9 +173,9 @@
GIInfoType type = g_base_info_get_type(container);
if (type == GI_INFO_TYPE_STRUCT || type == GI_INFO_TYPE_BOXED) {
- in_args[0].v_pointer = gjs_g_boxed_from_boxed(context, obj);
+ in_args[0].v_pointer = gjs_c_struct_from_boxed(context, obj);
} else if (type == GI_INFO_TYPE_UNION) {
- in_args[0].v_pointer = gjs_g_boxed_from_union(context, obj);
+ in_args[0].v_pointer = gjs_c_union_from_union(context, obj);
} else { /* by fallback is always object */
in_args[0].v_pointer = gjs_g_object_from_object(context, obj);
}
Modified: trunk/gi/union.c
==============================================================================
--- trunk/gi/union.c (original)
+++ trunk/gi/union.c Wed Nov 19 22:31:12 2008
@@ -178,7 +178,7 @@
if (JSVAL_IS_NULL(rval))
return NULL;
else
- return gjs_g_boxed_from_union(context, JSVAL_TO_OBJECT(rval));
+ return gjs_c_union_from_union(context, JSVAL_TO_OBJECT(rval));
}
g_base_info_unref((GIBaseInfo*) func_info);
@@ -429,6 +429,16 @@
JSObject *prototype;
jsval value;
Union *priv;
+ GType gtype;
+
+ /* For certain unions, we may be able to relax this in the future by
+ * directly allocating union memory, as we do for structures in boxed.c
+ */
+ gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) info);
+ if (gtype == G_TYPE_NONE) {
+ gjs_throw(context, "Unions must currently be registered as boxed types");
+ return JS_FALSE;
+ }
/* See the comment in gjs_define_object_class() for an
* explanation of how this all works; Union is pretty much the
@@ -522,38 +532,18 @@
}
JSObject*
-gjs_union_from_g_boxed(JSContext *context,
- GType gtype,
+gjs_union_from_c_union(JSContext *context,
+ GIUnionInfo *info,
void *gboxed)
{
- JSObject *obj;
JSObject *proto;
- GIBaseInfo *info;
if (gboxed == NULL)
return NULL;
gjs_debug_marshal(GJS_DEBUG_GBOXED,
"Wrapping union %s %p with JSObject",
- g_type_name(gtype), gboxed);
-
- info = g_irepository_find_by_gtype(g_irepository_get_default(),
- gtype);
-
- if (info == NULL) {
- gjs_throw(context,
- "Unknown union type %s",
- g_type_name(gtype));
- return NULL;
- }
-
- if (g_base_info_get_type( (GIBaseInfo*) info) != GI_INFO_TYPE_UNION) {
- gjs_throw(context,
- "GType %s doesn't map to union in g-i?",
- g_base_info_get_name( (GIBaseInfo*) info));
- g_base_info_unref( (GIBaseInfo*) info);
- return NULL;
- }
+ g_base_info_get_name((GBaseInfo *)info), gboxed);
proto = gjs_lookup_union_prototype(context, (GIUnionInfo*) info);
@@ -561,16 +551,12 @@
unthreadsafe_template_for_constructor.info = (GIUnionInfo*) info;
unthreadsafe_template_for_constructor.gboxed = gboxed;
- obj = gjs_construct_object_dynamic(context, proto,
- 0, NULL);
-
- g_base_info_unref( (GIBaseInfo*) info);
-
- return obj;
+ return gjs_construct_object_dynamic(context, proto,
+ 0, NULL);
}
void*
-gjs_g_boxed_from_union(JSContext *context,
+gjs_c_union_from_union(JSContext *context,
JSObject *obj)
{
Union *priv;
Modified: trunk/gi/union.h
==============================================================================
--- trunk/gi/union.h (original)
+++ trunk/gi/union.h Wed Nov 19 22:31:12 2008
@@ -43,10 +43,10 @@
GIUnionInfo *info);
JSClass* gjs_lookup_union_class (JSContext *context,
GIUnionInfo *info);
-void* gjs_g_boxed_from_union (JSContext *context,
+void* gjs_c_union_from_union (JSContext *context,
JSObject *obj);
-JSObject* gjs_union_from_g_boxed (JSContext *context,
- GType gtype,
+JSObject* gjs_union_from_c_union (JSContext *context,
+ GIUnionInfo *info,
void *gboxed);
G_END_DECLS
Modified: trunk/gi/value.c
==============================================================================
--- trunk/gi/value.c (original)
+++ trunk/gi/value.c Wed Nov 19 22:31:12 2008
@@ -324,7 +324,7 @@
} else if (JSVAL_IS_OBJECT(value)) {
JSObject *obj;
obj = JSVAL_TO_OBJECT(value);
- gboxed = gjs_g_boxed_from_boxed(context, obj);
+ gboxed = gjs_c_struct_from_boxed(context, obj);
} else {
gjs_throw(context,
"Wrong type %s; boxed type %s expected",
@@ -502,11 +502,27 @@
* their g-i info as both GBoxed */
info = g_irepository_find_by_gtype(g_irepository_get_default(),
gtype);
+ if (info == NULL) {
+ gjs_throw(context,
+ "No introspection information found for %s",
+ g_type_name(gtype));
+ return JS_FALSE;
+ }
- if (g_base_info_get_type(info) == GI_INFO_TYPE_UNION) {
- obj = gjs_union_from_g_boxed(context, gtype, gboxed);
- } else {
- obj = gjs_boxed_from_g_boxed(context, gtype, gboxed);
+ switch (g_base_info_get_type(info)) {
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed);
+ break;
+ case GI_INFO_TYPE_UNION:
+ obj = gjs_union_from_c_union(context, (GIUnionInfo *)info, gboxed);
+ break;
+ default:
+ gjs_throw(context,
+ "Unexpected introspection type %d for %s",
+ g_base_info_get_type(info),
+ g_type_name(gtype));
+ return JS_FALSE;
}
*value_p = OBJECT_TO_JSVAL(obj);
} else if (g_type_is_a(gtype, G_TYPE_ENUM)) {
Modified: trunk/test/js/testEverythingEncapsulated.js
==============================================================================
--- trunk/test/js/testEverythingEncapsulated.js (original)
+++ trunk/test/js/testEverythingEncapsulated.js Wed Nov 19 22:31:12 2008
@@ -1,5 +1,39 @@
const Everything = imports.gi.Everything;
+function testStruct() {
+ let struct = new Everything.TestStructA();
+ struct.some_int = 42;
+ struct.some_int8 = 43;
+ struct.some_double = 42.5;
+ assertEquals(42, struct.some_int);
+ assertEquals(43, struct.some_int8);
+ assertEquals(42.5, struct.some_double);
+}
+
+function testStructConstructor()
+{
+ // "Copy" an object from a hash of field values
+ let struct = new Everything.TestStructA({ some_int: 42,
+ some_int8: 43,
+ some_double: 42.5 });
+
+ assertEquals(42, struct.some_int);
+ assertEquals(43, struct.some_int8);
+ assertEquals(42.5, struct.some_double);
+
+ // Make sure we catch bad field names
+ assertRaises(function() {
+ let t = new Everything.TestStructA({ junk: 42 });
+ });
+
+ // Copy an object from another object of the same type, shortcuts to memcpy()
+ let copy = new Everything.TestStructA(struct);
+
+ assertEquals(42, copy.some_int);
+ assertEquals(43, copy.some_int8);
+ assertEquals(42.5, copy.some_double);
+}
+
function testSimpleBoxed() {
let simple_boxed = new Everything.TestSimpleBoxedA();
simple_boxed.some_int = 42;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]