[Swfdec-commits] Branch 'abc' - 3 commits - configure.ac swfdec/Makefile.am swfdec/swfdec_abc_class.c swfdec/swfdec_abc_file.c swfdec/swfdec_abc_file.h swfdec/swfdec_abc_function.c swfdec/swfdec_abc_function.h swfdec/swfdec_abc_global.c swfdec/swfdec_abc_internal.h swfdec/swfdec_abc_native.h swfdec/swfdec_abc_traits.h swfdec/swfdec_player_abc.c tools/abcextract.c
Benjamin Otte
company at kemper.freedesktop.org
Sat Aug 23 04:59:26 PDT 2008
configure.ac | 10 -
swfdec/Makefile.am | 7
swfdec/swfdec_abc_class.c | 11 -
swfdec/swfdec_abc_file.c | 121 +--------------
swfdec/swfdec_abc_file.h | 2
swfdec/swfdec_abc_function.c | 333 ++++++++++++++++++++++++++++++++++++++++++-
swfdec/swfdec_abc_function.h | 7
swfdec/swfdec_abc_global.c | 8 +
swfdec/swfdec_abc_internal.h | 7
swfdec/swfdec_abc_native.h | 4
swfdec/swfdec_abc_traits.h | 10 +
swfdec/swfdec_player_abc.c | 15 -
tools/abcextract.c | 2
13 files changed, 391 insertions(+), 146 deletions(-)
New commits:
commit 825c53d6795706716389de43317afb53f780361a
Merge: 1d39724... 70d2769...
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Aug 23 13:57:25 2008 +0200
Merge branch 'abc' of ssh://company@git.freedesktop.org/git/swfdec/swfdec into abc
Conflicts:
tools/abcextract.c
commit 1d397245d1475579cef5a0b670f2287c13f4081c
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Aug 23 13:51:56 2008 +0200
make native abc functions really be native
They go through libffi now
diff --git a/configure.ac b/configure.ac
index 644bcfb..67cc453 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,16 +187,12 @@ AC_SUBST(AUDIO_TYPE)
LIBOIL_VER=0.3.1
PKG_CHECK_MODULES(LIBOIL, liboil-0.3 >= $LIBOIL_VER, HAVE_LIBOIL=yes, HAVE_LIBOIL=no)
-AC_SUBST(LIBOIL_LIBS)
-AC_SUBST(LIBOIL_CFLAGS)
if test "$HAVE_LIBOIL" = "no"; then
AC_MSG_ERROR([liboil-0.3 >= $LIBOIL_VER is required to build swfdec])
fi
CAIRO_VER=1.6.0
PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VER cairo-png >= $CAIRO_VER, HAVE_CAIRO=yes, HAVE_CAIRO=no)
-AC_SUBST(CAIRO_LIBS)
-AC_SUBST(CAIRO_CFLAGS)
if test "$HAVE_CAIRO" = "no"; then
AC_MSG_ERROR([cairo and cairo-png = $CAIRO_VER is required to build swfdec])
fi
@@ -243,12 +239,14 @@ else
fi
AM_CONDITIONAL(HAVE_VIVI, [test "x$HAVE_VIVI" = xyes])
+FFI_VER=3.0.5
+PKG_CHECK_MODULES(FFI, libffi >= $FFI_VER)
AC_SUBST(GLOBAL_CFLAGS)
AC_SUBST(GLOBAL_CFLAGS)
-SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS $CAIRO_CFLAGS"
-SWFDEC_LIBS="\$(top_builddir)/swfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS $CAIRO_LIBS -lz -lm"
+SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS $CAIRO_CFLAGS $FFI_CFLAGS"
+SWFDEC_LIBS="\$(top_builddir)/swfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS $CAIRO_LIBS $FFI_LIBS -lz -lm"
AC_SUBST(SWFDEC_LIBS)
AC_SUBST(SWFDEC_CFLAGS)
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 0ae9df4..8a737f1 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -395,17 +395,16 @@ swfdec_abc_native.c: $(libswfdec_source_files)
&& echo "#include \"swfdec_abc_internal.h\"" \
&& echo "#undef SWFDEC_ABC_NATIVE" \
&& echo "#undef SWFDEC_ABC_FLASH" \
- && echo "#define SWFDEC_ABC_NATIVE(id,func) void func (SwfdecAsContext *cx, \\" \
- && echo " guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);" \
+ && echo "#define SWFDEC_ABC_NATIVE(id,func) void func (void);" \
&& echo "#define SWFDEC_ABC_FLASH SWFDEC_ABC_NATIVE" \
&& grep -he "^SWFDEC_ABC_NATIVE" $(libswfdec_source_files) \
&& grep -he "^SWFDEC_ABC_FLASH" $(libswfdec_source_files) \
&& echo "#undef SWFDEC_ABC_NATIVE" \
&& echo "#define SWFDEC_ABC_NATIVE(id,func) [id] = func," \
- && echo "const SwfdecAbcNative swfdec_abc_natives[585] = {" \
+ && echo "const GCallback swfdec_abc_natives[585] = {" \
&& grep -he "^SWFDEC_ABC_NATIVE" $(libswfdec_source_files) \
&& echo "};" \
- && echo "const SwfdecAbcNative swfdec_abc_natives_flash[1944] = {" \
+ && echo "const GCallback swfdec_abc_natives_flash[1944] = {" \
&& grep -he "^SWFDEC_ABC_FLASH" $(libswfdec_source_files) \
&& echo "};" \
&& echo "#undef SWFDEC_ABC_NATIVE" \
diff --git a/swfdec/swfdec_abc_class.c b/swfdec/swfdec_abc_class.c
index a7e5a65..31d99a6 100644
--- a/swfdec/swfdec_abc_class.c
+++ b/swfdec/swfdec_abc_class.c
@@ -136,17 +136,14 @@ swfdec_abc_class_init (SwfdecAbcClass *class)
/*** ABC CODE ***/
+void swfdec_abc_class_get_prototype (SwfdecAbcClass *classp, SwfdecAsValue *ret);
SWFDEC_ABC_NATIVE (29, swfdec_abc_class_get_prototype)
void
-swfdec_abc_class_get_prototype (SwfdecAsContext *cx,
- guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+swfdec_abc_class_get_prototype (SwfdecAbcClass *classp, SwfdecAsValue *ret)
{
- SwfdecAbcClass *classp = SWFDEC_ABC_CLASS (SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]));
-
- if (classp->prototype) {
+ if (classp->prototype)
SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (classp->prototype));
- } else {
+ else
SWFDEC_AS_VALUE_SET_NULL (ret);
- }
}
diff --git a/swfdec/swfdec_abc_file.c b/swfdec/swfdec_abc_file.c
index bddbaeb..b6d08d2 100644
--- a/swfdec/swfdec_abc_file.c
+++ b/swfdec/swfdec_abc_file.c
@@ -647,107 +647,9 @@ swfdec_abc_file_parse_traits (SwfdecAbcFile *file, SwfdecAbcTraits *traits, Swfd
return TRUE;
}
-static char *
-swfdec_abc_describe_function (SwfdecAbcFunction *function)
-{
- SwfdecAbcTraits *traits;
- GString *name;
- guint i, id;
-
- g_assert (function->resolved);
-
- /* find id of our function in pool */
- for (id = 0; id < function->pool->n_functions; id++) {
- if (function->pool->functions[id] == function)
- break;
- }
-
- traits = function->bound_traits;
- name = g_string_new ("");
- if (traits == NULL) {
- /* we're likely a lambda function */
- g_string_append_printf (name, "function %u: %s [lambda]", id,
- function->return_traits ? function->return_traits->name : "SwfdecAsValue *");
- } else if (traits->construct == function) {
- /* we're the constructor */
- g_string_append_printf (name, "function %u: %s %s", id,
- function->return_traits ? function->return_traits->name : "SwfdecAsValue *",
- traits->name);
- } else {
- /* we're method, getter or setter, find out what */
- do {
- for (i = 0; i < traits->n_traits; i++) {
- SwfdecAbcTrait *trait = &traits->traits[i];
- guint slot = SWFDEC_ABC_BINDING_GET_ID (trait->type);
- switch (SWFDEC_ABC_BINDING_GET_TYPE (trait->type)) {
- case SWFDEC_ABC_TRAIT_METHOD:
- if (traits->methods[slot] == function) {
- g_string_append_printf (name, "method %u %s %s.%s", id,
- function->return_traits ? function->return_traits->name : "SwfdecAsValue *",
- traits->name, trait->name);
- goto out;
- }
- break;
- case SWFDEC_ABC_TRAIT_GET:
- case SWFDEC_ABC_TRAIT_SET:
- case SWFDEC_ABC_TRAIT_GETSET:
- if (traits->methods[slot] == function) {
- g_string_append_printf (name, "getter %u %s %s.%s", id,
- function->return_traits ? function->return_traits->name : "SwfdecAsValue *",
- traits->name, trait->name);
- goto out;
- } else if (traits->methods[slot + 1] == function) {
- g_string_append_printf (name, "setter %u %s %s.%s", id,
- function->return_traits ? function->return_traits->name : "SwfdecAsValue *",
- traits->name, trait->name);
- goto out;
- }
- break;
- case SWFDEC_ABC_TRAIT_NONE:
- case SWFDEC_ABC_TRAIT_SLOT:
- case SWFDEC_ABC_TRAIT_CONST:
- case SWFDEC_ABC_TRAIT_ITRAMP:
- default:
- break;
- }
- }
- traits = traits->base;
- } while (traits);
- /* huh? */
- g_string_append_printf (name, "function %u %s %s", id,
- function->return_traits->name, function->bound_traits->name);
- }
-out:
- /* append arguments */
- g_string_append (name, " (");
- for (i = 0; i < function->n_args; i++) {
- if (i > 0)
- g_string_append (name, ", ");
- if (function->args[i].traits)
- g_string_append (name, function->args[i].traits->name);
- else
- g_string_append (name, "SwfdecAsValue *");
- }
- g_string_append (name, ")");
-
- return g_string_free (name, FALSE);
-}
-
-static void
-swfdec_abc_default_stub (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc,
- SwfdecAsValue *argv, SwfdecAsValue *ret)
-{
- SwfdecAsFrame *frame = swfdec_as_context_get_frame (cx);
- SwfdecAbcFunction *function = SWFDEC_ABC_FUNCTION (swfdec_as_frame_get_function (frame));
- char *name = swfdec_abc_describe_function (function);
-
- SWFDEC_STUB (name);
- g_free (name);
-}
-
static gboolean
swfdec_abc_file_parse_methods (SwfdecAbcFile *file, SwfdecBits *bits,
- const SwfdecAsNative *natives, guint n_natives)
+ const GCallback *natives, guint n_natives)
{
SwfdecAsContext *context = swfdec_gc_object_get_context (file);
guint i;
@@ -816,7 +718,6 @@ swfdec_abc_file_parse_methods (SwfdecAbcFile *file, SwfdecBits *bits,
}
if (fun->native == NULL) {
SWFDEC_INFO ("no native for index %u, using default stub", i);
- fun->native = swfdec_abc_default_stub;
}
}
if (optional) {
@@ -1120,7 +1021,7 @@ swfdec_abc_file_parse_bodies (SwfdecAbcFile *file, SwfdecBits *bits)
static gboolean
swfdec_abc_file_parse (SwfdecAbcFile *file, SwfdecBits *bits,
- const SwfdecAsNative *natives, guint n_natives)
+ const GCallback *natives, guint n_natives)
{
return swfdec_abc_file_parse_constants (file, bits) &&
swfdec_abc_file_parse_methods (file, bits, natives, n_natives) &&
@@ -1139,7 +1040,7 @@ swfdec_abc_file_new (SwfdecAsContext *context, SwfdecBits *bits)
SwfdecAbcFile *
swfdec_abc_file_new_trusted (SwfdecAsContext *context, SwfdecBits *bits,
- const SwfdecAsNative *natives, guint n_natives)
+ const GCallback *natives, guint n_natives)
{
SwfdecAbcFile *file;
guint major, minor;
@@ -1167,18 +1068,26 @@ swfdec_abc_file_new_trusted (SwfdecAsContext *context, SwfdecBits *bits,
return NULL;
}
-//#define SWFDEC_PRINT_STUBS
+#define SWFDEC_PRINT_STUBS
#ifdef SWFDEC_PRINT_STUBS
{
guint i;
if (SWFDEC_ABC_GLOBAL (context->global)->file == NULL)
SWFDEC_ABC_GLOBAL (context->global)->file = file;
+
+ /* update machine types */
+ SWFDEC_ABC_BOOLEAN_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+ SWFDEC_ABC_INT_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+ SWFDEC_ABC_UINT_TRAITS (context)->machine_type = SWFDEC_ABC_UINT;
+ SWFDEC_ABC_NUMBER_TRAITS (context)->machine_type = SWFDEC_ABC_DOUBLE;
+ SWFDEC_ABC_STRING_TRAITS (context)->machine_type = SWFDEC_ABC_STRING;
+
g_print ("missing implementations:\n");
for (i = 0; i < file->n_functions; i++) {
SwfdecAbcFunction *fun = file->functions[i];
char *name;
- if (fun->native == NULL)
+ if (fun->code != NULL)
continue;
/* This is why we can't print this stuff by default: We need to resolve
* the function, which could throw */
@@ -1186,8 +1095,8 @@ swfdec_abc_file_new_trusted (SwfdecAsContext *context, SwfdecBits *bits,
(fun->bound_traits != NULL && !swfdec_abc_traits_resolve (fun->bound_traits))) {
g_assert_not_reached ();
}
- name = swfdec_abc_describe_function (fun);
- g_print ("%s %s\n", fun->native == swfdec_abc_default_stub ? "XXX" : " ", name);
+ name = swfdec_abc_function_describe (fun);
+ g_print ("%s %s\n", fun->native == NULL ? "XXX" : " ", name);
g_free (name);
}
}
diff --git a/swfdec/swfdec_abc_file.h b/swfdec/swfdec_abc_file.h
index 675cf3e..776bc38 100644
--- a/swfdec/swfdec_abc_file.h
+++ b/swfdec/swfdec_abc_file.h
@@ -95,7 +95,7 @@ SwfdecAbcFile * swfdec_abc_file_new (SwfdecAsContext * context,
SwfdecBits * bits);
SwfdecAbcFile * swfdec_abc_file_new_trusted (SwfdecAsContext * context,
SwfdecBits * bits,
- const SwfdecAsNative * natives,
+ const GCallback * natives,
guint n_natives);
gboolean swfdec_abc_file_get_constant (SwfdecAbcFile * pool,
diff --git a/swfdec/swfdec_abc_function.c b/swfdec/swfdec_abc_function.c
index 9fe597d..9c4a2c6 100644
--- a/swfdec/swfdec_abc_function.c
+++ b/swfdec/swfdec_abc_function.c
@@ -30,8 +30,186 @@
#include "swfdec_abc_traits.h"
#include "swfdec_as_context.h"
#include "swfdec_as_frame_internal.h"
+#include "swfdec_as_strings.h" /* swfdec_abc_function_describe */
#include "swfdec_debug.h"
+/*** LIBFFI ***/
+
+static ffi_type *machine_types_ffi[] = {
+ [SWFDEC_ABC_POINTER] = &ffi_type_pointer,
+ [SWFDEC_ABC_INT] = &ffi_type_sint,
+ [SWFDEC_ABC_UINT] = &ffi_type_uint,
+ [SWFDEC_ABC_DOUBLE] = &ffi_type_double,
+ [SWFDEC_ABC_STRING] = &ffi_type_pointer,
+ [SWFDEC_ABC_VOID] = &ffi_type_void
+};
+
+static ffi_type *
+swfdec_abc_ffi_traits_to_type (SwfdecAbcTraits *traits)
+{
+ if (traits == NULL)
+ return &ffi_type_pointer;
+
+ return machine_types_ffi[traits->machine_type];
+}
+
+static guint
+swfdec_abc_function_native_n_arguments (SwfdecAbcFunction *fun)
+{
+ /* this pointer */
+ guint n_args = 1;
+ /* arguments */
+ n_args += fun->n_args;
+ /* add context as first arg if we're not passing an object */
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER)
+ n_args++;
+ /* append arguments: guint argc, SwfdecAsValue **argv */
+ if (fun->need_rest || fun->need_arguments)
+ n_args += 2;
+ /* append argument: SwfdecAsValue *retval */
+ if (fun->return_traits == NULL)
+ n_args++;
+ return n_args;
+}
+
+static gboolean
+swfdec_abc_function_ffi_verify (SwfdecAbcFunction *fun)
+{
+ guint i, n_args;
+ ffi_type **args;
+ ffi_type *ret;
+ ffi_status status;
+
+ /* prepare variables */
+ n_args = swfdec_abc_function_native_n_arguments (fun);
+ args = g_new (ffi_type *, n_args);
+
+ /* set argument types */
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER)
+ args[0] = &ffi_type_pointer;
+ for (i = 0; i <= fun->n_args; i++) {
+ args[i] = swfdec_abc_ffi_traits_to_type (fun->args[i].traits);
+ }
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER) {
+ args--;
+ i++;
+ }
+ if (fun->need_rest || fun->need_arguments) {
+ args[i++] = &ffi_type_uint;
+ args[i++] = &ffi_type_pointer;
+ }
+ if (fun->return_traits == NULL) {
+ ret = &ffi_type_void;
+ args[i++] = &ffi_type_pointer;
+ } else {
+ ret = swfdec_abc_ffi_traits_to_type (fun->return_traits);
+ }
+ g_assert (i == n_args);
+
+ /* prepare the cif */
+ status = ffi_prep_cif (&fun->cif, FFI_DEFAULT_ABI, n_args, ret, args);
+ //g_free (args);
+ if (status != FFI_OK) {
+ /* We don't have typedefs and we use the default abi, so this must not happen */
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+/* NB: @val must have been coerced to @traits */
+static gpointer
+swfdec_abc_ffi_get_address (SwfdecAbcTraits *traits, SwfdecAsValue *val)
+{
+ g_assert (traits != NULL);
+
+ /* make sure the value is NULL; */
+ if (SWFDEC_AS_VALUE_IS_NULL (val))
+ val->value.object = NULL;
+ /* FIXME: Is this correct, or do we need to do stuff like:
+ * if (SWFDEC_AS_VALUE_IS_BOOLEAN (val)) return &val.values.boolean
+ */
+ return &val->value;
+}
+
+static gboolean
+swfdec_abc_function_ffi_call (SwfdecAbcFunction *fun)
+{
+ SwfdecAsContext *context = swfdec_gc_object_get_context (fun);
+ SwfdecAsFrame *frame = context->frame;
+ SwfdecAsValue rval = { 0, };
+ const SwfdecAsValue *restp;
+ guint i, rest, n_args;
+ gpointer *args;
+ gpointer ret, rvalp;
+
+ /* compute number of arguments */
+ n_args = swfdec_abc_function_native_n_arguments (fun);
+ /* FIXME: I don't want a malloc here */
+ args = g_new (gpointer, n_args);
+
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER) {
+ args[0] = &context;
+ args++;
+ }
+ for (i = 0; i <= MIN (frame->argc, fun->n_args); i++) {
+ if (fun->args[i].traits == NULL) {
+ gconstpointer *tmp = g_newa (gconstpointer, 1);
+ *tmp = &frame->argv[i];
+ args[i] = &tmp;
+ } else {
+ args[i] = swfdec_abc_ffi_get_address (fun->args[i].traits, (gpointer) &frame->argv[i]);
+ }
+ }
+ for (; i <= fun->n_args; i++) {
+ if (fun->args[i].traits == NULL) {
+ gpointer *tmp = g_newa (gpointer, 1);
+ *tmp = &fun->args[i].default_value;
+ args[i] = &tmp;
+ } else {
+ args[i] = swfdec_abc_ffi_get_address (fun->args[i].traits,
+ &fun->args[i].default_value);
+ }
+ }
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER) {
+ args--;
+ i++;
+ }
+ if (fun->need_rest) {
+ if (frame->argc <= fun->n_args) {
+ rest = 0;
+ args[i++] = &rest;
+ args[i++] = &rval.value.object; /* should be a NULL value */
+ } else {
+ rest = frame->argc - fun->n_args;
+ restp = &frame->argv[fun->n_args];
+ args[i++] = &rest;
+ args[i++] = &restp;
+ }
+ } else if (fun->need_arguments) {
+ args[i++] = &frame->argc;
+ args[i++] = &frame->argv;
+ }
+ if (fun->return_traits == NULL) {
+ rvalp = &rval;
+ args[i++] = &rvalp;
+ ret = NULL;
+ } else {
+ ret = swfdec_abc_ffi_get_address (fun->return_traits, &rval);
+ }
+ g_assert (i == n_args);
+
+ ffi_call (&fun->cif, FFI_FN (fun->native), ret, args);
+ g_free (args);
+ if ((SWFDEC_AS_VALUE_IS_OBJECT (&rval) && rval.value.object == NULL) ||
+ (SWFDEC_AS_VALUE_IS_STRING (&rval) && rval.value.string == NULL) ||
+ (SWFDEC_AS_VALUE_IS_NAMESPACE (&rval) && rval.value.ns == NULL)) {
+ SWFDEC_AS_VALUE_SET_NULL (&rval);
+ }
+ swfdec_as_frame_return (frame, &rval);
+ return context->exception ? FALSE : TRUE;
+}
+
G_DEFINE_TYPE (SwfdecAbcFunction, swfdec_abc_function, SWFDEC_TYPE_GC_OBJECT)
static void
@@ -174,6 +352,9 @@ swfdec_abc_function_verify (SwfdecAbcFunction *fun)
if (!swfdec_abc_function_resolve (fun))
return FALSE;
+ if (fun->native)
+ return swfdec_abc_function_ffi_verify (fun);
+
if (!shut_up) {
SWFDEC_FIXME ("i can has verify?");
shut_up = TRUE;
@@ -271,11 +452,155 @@ swfdec_abc_function_call (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *scope,
frame.original_target = frame.target;
/* FIXME: coerce arguments */
if (fun->native) {
- SwfdecAsValue rval;
- ((SwfdecAbcNative) fun->native) (context, argc, argv, &rval);
+ return swfdec_abc_function_ffi_call (fun);
+ } else if (fun->code) {
+ return swfdec_abc_interpret (fun, scope);
+ } else {
+ /* no code and no native function, probably a missing stub */
+ SwfdecAsValue rval = { 0, };
+ char *desc = swfdec_abc_function_describe (fun);
+ SWFDEC_STUB (desc);
+ g_free (desc);
+ if (fun->return_traits && !swfdec_abc_traits_coerce (fun->return_traits, &rval))
+ return FALSE;
swfdec_as_frame_return (&frame, &rval);
- return context->exception ? FALSE : TRUE;
+ return TRUE;
+ }
+}
+
+static void
+swfdec_abc_function_append_name_for_traits (GString *string, SwfdecAbcTraits *traits)
+{
+ if (traits == NULL) {
+ g_string_append (string, "const SwfdecAsValue *");
+ return;
+ }
+
+ switch (traits->machine_type) {
+ case SWFDEC_ABC_POINTER:
+ g_string_append (string, "SwfdecAbc");
+ g_string_append (string, traits->name);
+ g_string_append (string, "*");
+ break;
+ case SWFDEC_ABC_INT:
+ if (traits->name == SWFDEC_AS_STR_Boolean)
+ g_string_append (string, "gboolean");
+ else
+ g_string_append (string, "int");
+ break;
+ case SWFDEC_ABC_UINT:
+ g_string_append (string, "guint");
+ break;
+ case SWFDEC_ABC_DOUBLE:
+ g_string_append (string, "double");
+ break;
+ case SWFDEC_ABC_STRING:
+ g_string_append (string, "const char*");
+ break;
+ case SWFDEC_ABC_VOID:
+ g_string_append (string, "void");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+char *
+swfdec_abc_function_describe (SwfdecAbcFunction *fun)
+{
+ SwfdecAbcTraits *traits;
+ GString *name, *retname;
+ guint i, id;
+
+ g_assert (fun->resolved);
+
+ /* find id of our function in pool */
+ for (id = 0; id < fun->pool->n_functions; id++) {
+ if (fun->pool->functions[id] == fun)
+ break;
+ }
+
+ traits = fun->bound_traits;
+ name = g_string_new ("");
+ if (fun->return_traits == NULL) {
+ retname = g_string_new ("void");
} else {
- return swfdec_abc_interpret (fun, scope);
+ retname = g_string_new ("");
+ swfdec_abc_function_append_name_for_traits (retname, fun->return_traits);
}
+ if (traits == NULL) {
+ /* we're likely a lambda function */
+ g_string_append_printf (name, "function %u: %s [lambda]", id, retname->str);
+ } else if (traits->construct == fun) {
+ /* we're the constructor */
+ g_string_append_printf (name, "function %u: %s %s", id,
+ retname->str, traits->name);
+ } else {
+ /* we're method, getter or setter, find out what */
+ do {
+ for (i = 0; i < traits->n_traits; i++) {
+ SwfdecAbcTrait *trait = &traits->traits[i];
+ guint slot = SWFDEC_ABC_BINDING_GET_ID (trait->type);
+ switch (SWFDEC_ABC_BINDING_GET_TYPE (trait->type)) {
+ case SWFDEC_ABC_TRAIT_METHOD:
+ if (traits->methods[slot] == fun) {
+ g_string_append_printf (name, "method %u %s %s.%s", id,
+ retname->str, traits->name, trait->name);
+ goto out;
+ }
+ break;
+ case SWFDEC_ABC_TRAIT_GET:
+ case SWFDEC_ABC_TRAIT_SET:
+ case SWFDEC_ABC_TRAIT_GETSET:
+ if (traits->methods[slot] == fun) {
+ g_string_append_printf (name, "getter %u %s %s.%s", id,
+ retname->str, traits->name, trait->name);
+ goto out;
+ } else if (traits->methods[slot + 1] == fun) {
+ g_string_append_printf (name, "setter %u %s %s.%s", id,
+ retname->str, traits->name, trait->name);
+ goto out;
+ }
+ break;
+ case SWFDEC_ABC_TRAIT_NONE:
+ case SWFDEC_ABC_TRAIT_SLOT:
+ case SWFDEC_ABC_TRAIT_CONST:
+ case SWFDEC_ABC_TRAIT_ITRAMP:
+ default:
+ break;
+ }
+ }
+ traits = traits->base;
+ } while (traits);
+ /* huh? */
+ g_string_append_printf (name, "function %u %s %s", id, retname->str,
+ fun->bound_traits->name);
+ }
+out:
+ /* append arguments */
+ g_string_append (name, " (");
+ if (fun->args[0].traits->machine_type != SWFDEC_ABC_POINTER)
+ g_string_append (name, "SwfdecAsContext *cx, ");
+ for (i = 0; i <= fun->n_args; i++) {
+ if (i > 0)
+ g_string_append (name, ", ");
+ swfdec_abc_function_append_name_for_traits (name, fun->args[i].traits);
+ if (i > 0)
+ g_string_append_printf (name, " arg%u", i);
+ else
+ g_string_append (name, " thisp");
+ }
+ if (fun->need_rest) {
+ g_string_append (name, ", guint argc, SwfdecAsValue *rest");
+ } else if (fun->need_arguments) {
+ g_string_append (name, ", guint argc, SwfdecAsValue *argv");
+ }
+ if (fun->return_type == NULL) {
+ g_string_append (name, ", SwfdecAsValue *ret");
+ }
+ g_string_append (name, ")");
+
+ g_string_free (retname, TRUE);
+ return g_string_free (name, FALSE);
}
+
diff --git a/swfdec/swfdec_abc_function.h b/swfdec/swfdec_abc_function.h
index c5ee816..696b71d 100644
--- a/swfdec/swfdec_abc_function.h
+++ b/swfdec/swfdec_abc_function.h
@@ -20,6 +20,8 @@
#ifndef _SWFDEC_ABC_FUNCTION_H_
#define _SWFDEC_ABC_FUNCTION_H_
+#include <ffi.h>
+
#include <swfdec/swfdec_abc_types.h>
#include <swfdec/swfdec_as_function.h>
#include <swfdec/swfdec_buffer.h>
@@ -84,7 +86,8 @@ struct _SwfdecAbcFunction {
SwfdecAbcTraits * bound_traits; /* traits of objects we construct or NULL */
/* native functions only */
- SwfdecAsNative native; /* SwfdecAsNative for now - will become native when we can marhsal */
+ GCallback native; /* SwfdecAsNative for now - will become native when we can marhsal */
+ ffi_cif cif; /* native call marshaller - prepared during verification */
/* functions with body only */
SwfdecBuffer * code; /* the code to be executed */
guint n_stack; /* max number of values on stack */
@@ -115,6 +118,8 @@ gboolean swfdec_abc_function_call (SwfdecAbcFunction * fun,
SwfdecAsValue * argv,
SwfdecAsValue * ret);
+char * swfdec_abc_function_describe (SwfdecAbcFunction * fun);
+
G_END_DECLS
#endif
diff --git a/swfdec/swfdec_abc_global.c b/swfdec/swfdec_abc_global.c
index 0e6aae6..1dd8c29 100644
--- a/swfdec/swfdec_abc_global.c
+++ b/swfdec/swfdec_abc_global.c
@@ -77,6 +77,7 @@ swfdec_abc_global_constructor (GType type, guint n_construct_properties,
global->void_traits->pool = NULL;
global->void_traits->ns = context->public_ns;
global->void_traits->name = SWFDEC_AS_STR_void;
+ global->void_traits->machine_type = SWFDEC_ABC_VOID;
global->void_traits->final = TRUE;
global->void_traits->resolved = TRUE;
global->null_traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
@@ -107,6 +108,13 @@ swfdec_abc_global_constructor (GType type, guint n_construct_properties,
SWFDEC_ABC_OBJECT (global)->slots = swfdec_as_context_new (context,
SwfdecAsValue, traits->n_slots);
+ /* update machine types */
+ SWFDEC_ABC_BOOLEAN_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+ SWFDEC_ABC_INT_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+ SWFDEC_ABC_UINT_TRAITS (context)->machine_type = SWFDEC_ABC_UINT;
+ SWFDEC_ABC_NUMBER_TRAITS (context)->machine_type = SWFDEC_ABC_DOUBLE;
+ SWFDEC_ABC_STRING_TRAITS (context)->machine_type = SWFDEC_ABC_STRING;
+
/* run main script */
global->file->main->global = SWFDEC_ABC_OBJECT (global);
SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (global));
diff --git a/swfdec/swfdec_abc_internal.h b/swfdec/swfdec_abc_internal.h
index 9e0157a..62bbb5f 100644
--- a/swfdec/swfdec_abc_internal.h
+++ b/swfdec/swfdec_abc_internal.h
@@ -26,11 +26,8 @@
G_BEGIN_DECLS
-#define SWFDEC_ABC_NATIVE(id, func) void func (SwfdecAsContext *cx, \
- guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);
-#define SWFDEC_ABC_FLASH(id, func) void func (SwfdecAsContext *cx, \
- guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);
-typedef void (* SwfdecAbcNative) (SwfdecAsContext *cx, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);
+#define SWFDEC_ABC_NATIVE(id, func)
+#define SWFDEC_ABC_FLASH(id, func)
/* This header contains all private symbols of Abc handling that should not be
* exported in the API */
diff --git a/swfdec/swfdec_abc_native.h b/swfdec/swfdec_abc_native.h
index 47a5514..3b9a06c 100644
--- a/swfdec/swfdec_abc_native.h
+++ b/swfdec/swfdec_abc_native.h
@@ -25,9 +25,9 @@
G_BEGIN_DECLS
-extern const SwfdecAsNative swfdec_abc_natives[585];
+extern const GCallback swfdec_abc_natives[585];
-extern const SwfdecAsNative swfdec_abc_natives_flash[1944];
+extern const GCallback swfdec_abc_natives_flash[1944];
G_END_DECLS
diff --git a/swfdec/swfdec_abc_traits.h b/swfdec/swfdec_abc_traits.h
index a5ecf4b..f8af61d 100644
--- a/swfdec/swfdec_abc_traits.h
+++ b/swfdec/swfdec_abc_traits.h
@@ -26,6 +26,15 @@
G_BEGIN_DECLS
+typedef enum {
+ SWFDEC_ABC_POINTER = 0,
+ SWFDEC_ABC_INT,
+ SWFDEC_ABC_UINT,
+ SWFDEC_ABC_DOUBLE,
+ SWFDEC_ABC_STRING,
+ SWFDEC_ABC_VOID
+} SwfdecAbcMachineType;
+
/* NB: The indexes for the binding types have a lot of magic associated with
* them, so be sure to update this magic. Examples:
* (type & 6) == 2 => slot or const
@@ -92,6 +101,7 @@ struct _SwfdecAbcTraits {
SwfdecAbcFunction * construct; /* constructor for objects of these traits or NULL */
SwfdecAbcNamespace * protected_ns; /* protected namespace */
GType (* type_func) (void); /* get_type function for the object type we create */
+ SwfdecAbcMachineType machine_type; /* how this type is represented */
SwfdecAbcTrait * traits; /* the traits we have */
guint n_traits; /* number of traits */
diff --git a/swfdec/swfdec_player_abc.c b/swfdec/swfdec_player_abc.c
index 5b49d5e..75a22d0 100644
--- a/swfdec/swfdec_player_abc.c
+++ b/swfdec/swfdec_player_abc.c
@@ -26,11 +26,12 @@
#include "swfdec_abc_internal.h"
#include "swfdec_resource.h"
+void swfdec_player_abc_trace (SwfdecAsObject *global, guint argc, SwfdecAsValue *argv);
SWFDEC_ABC_FLASH (0, swfdec_player_abc_trace)
void
-swfdec_player_abc_trace (SwfdecAsContext *cx,
- guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+swfdec_player_abc_trace (SwfdecAsObject *global, guint argc, SwfdecAsValue *argv)
{
+ SwfdecAsContext *cx = swfdec_gc_object_get_context (global);
GString *string = g_string_new ("");
guint i;
@@ -44,16 +45,12 @@ swfdec_player_abc_trace (SwfdecAsContext *cx,
g_string_free (string, TRUE);
}
+void swfdec_player_abc_fscommand (SwfdecAsObject *system, const char *command, const char *target);
SWFDEC_ABC_FLASH (203, swfdec_player_abc_fscommand)
void
-swfdec_player_abc_fscommand (SwfdecAsContext *cx,
- guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+swfdec_player_abc_fscommand (SwfdecAsObject *system, const char *command, const char *target)
{
- const char *command, *target;
-
- command = swfdec_as_value_to_string (cx, &argv[1]);
- target = swfdec_as_value_to_string (cx, &argv[2]);
-
+ SwfdecAsContext *cx = swfdec_gc_object_get_context (system);
/* FIXME: emit here or (as in older Flash) later? */
g_signal_emit_by_name (cx, "fscommand", command, target);
}
commit 39efcd6a8d691107f43f9822c9db08cf891600d5
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Aug 22 14:32:06 2008 +0100
make it compile again
Small little problem: The new code initializes the Tamarin ABC stuff, so we
can't parse those without errors anymore
diff --git a/tools/abcextract.c b/tools/abcextract.c
index 12028c1..3f31c23 100644
--- a/tools/abcextract.c
+++ b/tools/abcextract.c
@@ -116,7 +116,7 @@ main (int argc, char **argv)
}
cx = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
- swfdec_abc_global_new (cx);
+ swfdec_as_context_startup (cx, TRUE);
offsets = g_ptr_array_new ();
for (i = 0; i < buffer->length - 3; i++) {
if (buffer->data[i] != 0x10 ||
More information about the Swfdec-commits
mailing list