[Swfdec] Branch 'as' - 8 commits - libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_math.c libswfdec/swfdec_as_math.h libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_types.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_tag.c
Benjamin Otte
company at kemper.freedesktop.org
Tue May 29 00:28:28 PDT 2007
libswfdec/Makefile.am | 2
libswfdec/swfdec_as_array.c | 10 ++++
libswfdec/swfdec_as_context.c | 18 ++++++-
libswfdec/swfdec_as_interpret.c | 100 +++++++++++++++++++++++++++-------------
libswfdec/swfdec_as_math.c | 58 +++++++++++++++++++++++
libswfdec/swfdec_as_math.h | 33 +++++++++++++
libswfdec/swfdec_as_strings.c | 4 +
libswfdec/swfdec_as_types.c | 14 ++---
libswfdec/swfdec_sprite_movie.c | 5 +-
libswfdec/swfdec_tag.c | 7 ++
10 files changed, 208 insertions(+), 43 deletions(-)
New commits:
diff-tree dc6c1becbfb201aa15c126c05ba38e4c772fac80 (from 87277c93fa313582d4ee63ead97538e047257bc7)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 20:15:22 2007 +0200
don't crash if a DefineSprite has no ShowFrame tag
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 319c878..3e25eb9 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -166,8 +166,8 @@ swfdec_sprite_movie_goto (SwfdecMovie *m
g_assert (goto_frame < mov->n_frames);
if (goto_frame >= movie->sprite->parse_frame) {
- SWFDEC_WARNING ("jumping to not-yet-loaded frame %u (loaded: %u)",
- goto_frame, movie->sprite->parse_frame);
+ SWFDEC_WARNING ("jumping to not-yet-loaded frame %u (loaded: %u/%u)",
+ goto_frame, movie->sprite->parse_frame, movie->sprite->n_frames);
return;
}
@@ -312,6 +312,7 @@ swfdec_sprite_movie_init_movie (SwfdecMo
SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
mov->n_frames = movie->sprite->n_frames;
+ g_assert (movie->sprite->parse_frame > 0);
swfdec_sprite_movie_goto (mov, 0);
if (!swfdec_sprite_movie_iterate_end (mov)) {
g_assert_not_reached ();
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index 4e59456..7df13f4 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -252,6 +252,13 @@ tag_func_define_sprite (SwfdecSwfDecoder
}
}
+ /* sanity check the sprite */
+ if (s->parse_sprite->n_frames != s->parse_sprite->parse_frame) {
+ SWFDEC_ERROR ("not enough frames in sprite %u (have %u, want %u), filling up with empty frames",
+ id, s->parse_sprite->parse_frame, s->parse_sprite->n_frames);
+ s->parse_sprite->parse_frame = s->parse_sprite->n_frames;
+ }
+
s->b = parse;
/* this assumes that no recursive DefineSprite happens and we check it doesn't */
s->parse_sprite = s->main_sprite;
diff-tree 87277c93fa313582d4ee63ead97538e047257bc7 (from 0bd5c28a8bb10533dc2962d2957c44cf6e1bafb4)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 19:05:12 2007 +0200
add Math object and ceil function
diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index ba1f4d4..4434221 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -36,6 +36,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
swfdec_as_frame.c \
swfdec_as_function.c \
swfdec_as_interpret.c \
+ swfdec_as_math.c \
swfdec_as_native_function.c \
swfdec_as_number.c \
swfdec_as_object.c \
@@ -137,6 +138,7 @@ noinst_HEADERS = \
swfdec_as_frame.h \
swfdec_as_function.h \
swfdec_as_interpret.h \
+ swfdec_as_math.h \
swfdec_as_native_function.h \
swfdec_as_number.h \
swfdec_as_object.h \
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index b2556a5..72aaefa 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -28,6 +28,7 @@
#include "swfdec_as_frame.h"
#include "swfdec_as_function.h"
#include "swfdec_as_interpret.h"
+#include "swfdec_as_math.h"
#include "swfdec_as_native_function.h"
#include "swfdec_as_number.h"
#include "swfdec_as_object.h"
@@ -797,13 +798,17 @@ swfdec_as_context_startup (SwfdecAsConte
g_return_if_fail (context->state == SWFDEC_AS_CONTEXT_NEW);
context->version = version;
+ /* get the necessary objects up to define objects and functions sanely */
swfdec_as_function_init_context (context, version);
swfdec_as_object_init_context (context, version);
-
+ /* define the global object and other important ones */
swfdec_as_context_init_global (context, version);
swfdec_as_array_init_context (context, version);
-
+ /* define the type objects */
swfdec_as_number_init_context (context, version);
+ /* define the rest */
+ swfdec_as_math_init_context (context, version);
+
if (context->state == SWFDEC_AS_CONTEXT_NEW)
context->state = SWFDEC_AS_CONTEXT_RUNNING;
}
diff --git a/libswfdec/swfdec_as_math.c b/libswfdec/swfdec_as_math.c
new file mode 100644
index 0000000..5006bd8
--- /dev/null
+++ b/libswfdec/swfdec_as_math.c
@@ -0,0 +1,58 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+
+#include "swfdec_as_math.h"
+#include "swfdec_as_object.h"
+#include "swfdec_as_context.h"
+#include "swfdec_debug.h"
+
+/*** AS CODE ***/
+
+static void
+swfdec_as_math_ceil (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+ double d = swfdec_as_value_to_number (object->context, &argv[0]);
+
+ d = ceil (d);
+ SWFDEC_AS_VALUE_SET_NUMBER (ret, d);
+}
+
+void
+swfdec_as_math_init_context (SwfdecAsContext *context, guint version)
+{
+ SwfdecAsObject *math;
+ SwfdecAsValue val;
+
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+
+ math = swfdec_as_object_new (context);
+ if (math == NULL)
+ return;
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, math);
+ swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR_Math, &val);
+ /* set the right properties on the Math object */
+ swfdec_as_object_add_function (math, SWFDEC_AS_STR_ceil, 0, swfdec_as_math_ceil, 1);
+}
+
diff --git a/libswfdec/swfdec_as_math.h b/libswfdec/swfdec_as_math.h
new file mode 100644
index 0000000..80b1452
--- /dev/null
+++ b/libswfdec/swfdec_as_math.h
@@ -0,0 +1,33 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_AS_MATH_H_
+#define _SWFDEC_AS_MATH_H_
+
+#include <libswfdec/swfdec_as_types.h>
+
+G_BEGIN_DECLS
+
+
+void swfdec_as_math_init_context (SwfdecAsContext * context,
+ guint version);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 995d3c7..bee63bd 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -165,6 +165,8 @@ const char swfdec_as_strings[] =
SWFDEC_AS_CONSTANT_STRING ("Color")
SWFDEC_AS_CONSTANT_STRING ("push")
SWFDEC_AS_CONSTANT_STRING ("parseInt")
+ SWFDEC_AS_CONSTANT_STRING ("Math")
+ SWFDEC_AS_CONSTANT_STRING ("ceil")
/* add more here */
;
diff-tree 0bd5c28a8bb10533dc2962d2957c44cf6e1bafb4 (from b5cddf5ee7be4ec7c966a61692b4f3fe37e35b75)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 18:41:05 2007 +0200
try harder to get the name for debug messages in CallMethod
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 59dcf68..bcea772 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -669,6 +669,8 @@ swfdec_action_call_method (SwfdecAsConte
swfdec_as_object_get_variable (obj, name, swfdec_as_stack_peek (frame->stack, 2));
}
} else {
+ if (SWFDEC_AS_VALUE_IS_STRING (val))
+ name = SWFDEC_AS_VALUE_GET_STRING (val);
SWFDEC_AS_VALUE_SET_NULL (swfdec_as_stack_peek (frame->stack, 3));
SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 2));
}
diff-tree b5cddf5ee7be4ec7c966a61692b4f3fe37e35b75 (from 228f4e1eba33dcdd45634a44c3c5736e3963c982)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 18:32:06 2007 +0200
implement parseInt
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index d44024d..b2556a5 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -760,6 +760,13 @@ swfdec_as_context_ASSetPropFlags (Swfdec
}
static void
+swfdec_as_context_parseInt (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+ int i = swfdec_as_value_to_integer (object->context, &argv[0]);
+ SWFDEC_AS_VALUE_SET_INT (retval, i);
+}
+
+static void
swfdec_as_context_init_global (SwfdecAsContext *context, guint version)
{
SwfdecAsValue val;
@@ -770,6 +777,8 @@ swfdec_as_context_init_global (SwfdecAsC
swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR_NaN, &val);
SWFDEC_AS_VALUE_SET_NUMBER (&val, HUGE_VAL);
swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR_Infinity, &val);
+ swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_parseInt, 0,
+ swfdec_as_context_parseInt, 1);
}
/**
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index acafe6b..995d3c7 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -164,6 +164,7 @@ const char swfdec_as_strings[] =
SWFDEC_AS_CONSTANT_STRING ("setTransform")
SWFDEC_AS_CONSTANT_STRING ("Color")
SWFDEC_AS_CONSTANT_STRING ("push")
+ SWFDEC_AS_CONSTANT_STRING ("parseInt")
/* add more here */
;
diff-tree 228f4e1eba33dcdd45634a44c3c5736e3963c982 (from 7a616f11092554851aede853537d78a77374826c)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 17:24:42 2007 +0200
allow swfdec_as_value_to_primitive() to return objects
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 2004e71..22b528f 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -257,11 +257,12 @@ swfdec_as_value_to_number (SwfdecAsConte
return NAN;
d = g_ascii_strtod (s, &end);
if (*end == '\0')
- return d;
+ return d == -0.0 ? 0.0 : d;
else
return NAN;
}
case SWFDEC_AS_TYPE_OBJECT:
+ return NAN;
default:
g_assert_not_reached ();
return NAN;
@@ -360,10 +361,10 @@ swfdec_as_value_to_boolean (SwfdecAsCont
* @context: a #SwfdecAsContext
* @value: value to convert
*
- * Converts the given @value inline to its primitive value. Primitive values
- * are values that are not objects. If the value is an object, the object's
- * valueOf function is called. If the result of that function is still an
- * object, @value is set to undefined.
+ * Tries to convert the given @value inline to its primitive value. Primitive
+ * values are values that are not objects. If the value is an object, the
+ * object's valueOf function is called. If the result of that function is still
+ * an object, it is returned nonetheless.
**/
void
swfdec_as_value_to_primitive (SwfdecAsValue *value)
@@ -373,9 +374,6 @@ swfdec_as_value_to_primitive (SwfdecAsVa
if (SWFDEC_AS_VALUE_IS_OBJECT (value)) {
swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_valueOf,
0, NULL, value);
- if (SWFDEC_AS_VALUE_IS_OBJECT (value)) {
- SWFDEC_AS_VALUE_SET_UNDEFINED (value);
- }
}
}
diff-tree 7a616f11092554851aede853537d78a77374826c (from b1af12501a718c910eb88c7052cb500058c2269c)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun May 27 17:24:12 2007 +0200
forgot to commit required string
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 52b4d01..acafe6b 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -163,6 +163,7 @@ const char swfdec_as_strings[] =
SWFDEC_AS_CONSTANT_STRING ("setRGB")
SWFDEC_AS_CONSTANT_STRING ("setTransform")
SWFDEC_AS_CONSTANT_STRING ("Color")
+ SWFDEC_AS_CONSTANT_STRING ("push")
/* add more here */
;
diff-tree b1af12501a718c910eb88c7052cb500058c2269c (from 63f4eba1aa82473a2185f78c37db0ace7b0343e3)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri May 25 13:07:34 2007 +0200
initial try at implementing Equals2 action correctly
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 70f5f78..59dcf68 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -968,48 +968,84 @@ swfdec_action_equals2 (SwfdecAsContext *
{
SwfdecAsValue *rval, *lval;
SwfdecAsType ltype, rtype;
+ double l, r;
gboolean cond;
rval = swfdec_as_stack_peek (cx->frame->stack, 1);
lval = swfdec_as_stack_peek (cx->frame->stack, 2);
ltype = lval->type;
rtype = rval->type;
- if (ltype == rtype) {
- switch (ltype) {
- case SWFDEC_AS_TYPE_UNDEFINED:
- case SWFDEC_AS_TYPE_NULL:
- cond = TRUE;
- break;
- case SWFDEC_AS_TYPE_BOOLEAN:
- cond = SWFDEC_AS_VALUE_GET_BOOLEAN (lval) == SWFDEC_AS_VALUE_GET_BOOLEAN (rval);
- break;
- case SWFDEC_AS_TYPE_NUMBER:
- cond = SWFDEC_AS_VALUE_GET_NUMBER (lval) == SWFDEC_AS_VALUE_GET_NUMBER (rval);
- break;
- case SWFDEC_AS_TYPE_STRING:
- cond = SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval);
- break;
- case SWFDEC_AS_TYPE_OBJECT:
- cond = SWFDEC_AS_VALUE_GET_OBJECT (lval) == SWFDEC_AS_VALUE_GET_OBJECT (rval);
- break;
- default:
- g_assert_not_reached ();
+
+ /* get objects compared */
+ if (ltype == SWFDEC_AS_TYPE_OBJECT && rtype == SWFDEC_AS_TYPE_OBJECT) {
+ SwfdecAsObject *lo = SWFDEC_AS_VALUE_GET_OBJECT (lval);
+ SwfdecAsObject *ro = SWFDEC_AS_VALUE_GET_OBJECT (rval);
+
+ if (SWFDEC_IS_MOVIE (lo) && SWFDEC_IS_MOVIE (ro)) {
+ /* do nothing */
+ } else if (SWFDEC_IS_MOVIE (lo)) {
+ swfdec_as_value_to_primitive (rval);
+ rtype = rval->type;
+ if (rtype != SWFDEC_AS_TYPE_OBJECT) {
cond = FALSE;
- break;
+ goto out;
+ }
+ ro = SWFDEC_AS_VALUE_GET_OBJECT (rval);
+ } else if (SWFDEC_IS_MOVIE (ro)) {
+ swfdec_as_value_to_primitive (lval);
+ ltype = lval->type;
+ if (ltype != SWFDEC_AS_TYPE_OBJECT) {
+ cond = FALSE;
+ goto out;
+ }
+ lo = SWFDEC_AS_VALUE_GET_OBJECT (lval);
}
- } else {
- if (ltype == SWFDEC_AS_TYPE_UNDEFINED || ltype == SWFDEC_AS_TYPE_NULL) {
- cond = (rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL);
- } else if (rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL) {
+ cond = lo == ro;
+ goto out;
+ }
+
+ /* if one of the values is an object, call valueOf.
+ * If it's still an object, return FALSE */
+ if (ltype == SWFDEC_AS_TYPE_OBJECT) {
+ swfdec_as_value_to_primitive (lval);
+ ltype = lval->type;
+ if (ltype == SWFDEC_AS_TYPE_OBJECT) {
cond = FALSE;
- } else {
- SWFDEC_WARNING ("FIXME: test equality operations between non-equal types");
- double l, r;
- r = swfdec_as_value_to_number (cx, rval);
- l = swfdec_as_value_to_number (cx, lval);
- cond = r == l;
+ goto out;
}
}
+ if (rtype == SWFDEC_AS_TYPE_OBJECT) {
+ swfdec_as_value_to_primitive (rval);
+ rtype = rval->type;
+ if (rtype == SWFDEC_AS_TYPE_OBJECT) {
+ cond = FALSE;
+ goto out;
+ }
+ }
+ /* now we have a comparison without objects */
+
+ /* get rid of undefined and null */
+ cond = rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL;
+ if (ltype == SWFDEC_AS_TYPE_UNDEFINED || ltype == SWFDEC_AS_TYPE_NULL) {
+ goto out;
+ } else if (cond) {
+ cond = FALSE;
+ goto out;
+ }
+
+ /* compare strings */
+ if (ltype == SWFDEC_AS_TYPE_STRING && rtype == SWFDEC_AS_TYPE_STRING) {
+ /* FIXME: flash 5 case insensitive? */
+ cond = SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval);
+ goto out;
+ }
+
+ /* else compare as numbers */
+ l = swfdec_as_value_to_number (cx, lval);
+ r = swfdec_as_value_to_number (cx, rval);
+ cond = l == r;
+
+out:
swfdec_as_stack_pop (cx->frame->stack);
SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), cond);
}
diff-tree 63f4eba1aa82473a2185f78c37db0ace7b0343e3 (from b0c6f9795a20bb5e9f98e3f1afe286d81bbef7a2)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri May 25 13:06:53 2007 +0200
implement Array.push()
diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index b47faac..b49e178 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -184,6 +184,15 @@ swfdec_as_array_toString (SwfdecAsObject
SWFDEC_AS_VALUE_SET_STRING (ret, str);
}
+static void
+swfdec_as_array_do_push (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+ SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
+
+ swfdec_as_array_append (array, argc, argv);
+ SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object));
+}
+
void
swfdec_as_array_init_context (SwfdecAsContext *context, guint version)
{
@@ -224,5 +233,6 @@ swfdec_as_array_init_context (SwfdecAsCo
SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0, swfdec_as_array_toString, 0);
+ swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push, SWFDEC_TYPE_AS_ARRAY, swfdec_as_array_do_push, 0);
}
More information about the Swfdec
mailing list