[Swfdec] Branch 'as' - 15 commits - libswfdec/swfdec_as_context.c
libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c
libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c
libswfdec/swfdec_as_function.h
libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c
libswfdec/swfdec_as_object.h libswfdec/swfdec_as_types.c
libswfdec/swfdec_as_types.h libswfdec/swfdec_button_movie.c
libswfdec/swfdec_connection.c libswfdec/swfdec_debugger.c
libswfdec/swfdec_listener.c libswfdec/swfdec_movie.c
libswfdec/swfdec_net_stream.c libswfdec/swfdec_script.c
libswfdec/swfdec_xml.c player/swfdec_debug_widget.c
Benjamin Otte
company at kemper.freedesktop.org
Thu Apr 12 05:07:01 PDT 2007
libswfdec/swfdec_as_context.c | 29 ++--
libswfdec/swfdec_as_context.h | 5
libswfdec/swfdec_as_frame.c | 47 +++++-
libswfdec/swfdec_as_frame.h | 7 -
libswfdec/swfdec_as_function.c | 12 +
libswfdec/swfdec_as_function.h | 4
libswfdec/swfdec_as_interpret.c | 270 +++++++++++++++++++---------------------
libswfdec/swfdec_as_object.c | 31 ++++
libswfdec/swfdec_as_object.h | 3
libswfdec/swfdec_as_types.c | 24 ++-
libswfdec/swfdec_as_types.h | 4
libswfdec/swfdec_button_movie.c | 2
libswfdec/swfdec_connection.c | 2
libswfdec/swfdec_debugger.c | 25 +--
libswfdec/swfdec_listener.c | 2
libswfdec/swfdec_movie.c | 2
libswfdec/swfdec_net_stream.c | 4
libswfdec/swfdec_script.c | 9 -
libswfdec/swfdec_xml.c | 2
player/swfdec_debug_widget.c | 2
20 files changed, 285 insertions(+), 201 deletions(-)
New commits:
diff-tree 02593459b3315d147733872fef67bdb8fb5396d0 (from f47891d0c97c9679dc4234c83866948ace3d1d50)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 14:06:35 2007 +0200
ensxure printing an action always returns a string, even if its just "error"
diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index 71b3ee7..1daf62a 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -70,10 +70,8 @@ swfdec_debugger_print_push (ScriptParser
case 0: /* string */
{
const char *s = swfdec_bits_skip_string (&bits);
- if (!s) {
- g_string_free (string, TRUE);
- return NULL;
- }
+ if (!s)
+ goto error;
g_string_append_c (string, '"');
g_string_append (string, s);
g_string_append_c (string, '"');
@@ -108,15 +106,13 @@ swfdec_debugger_print_push (ScriptParser
if (!parser->constant_pool) {
SWFDEC_ERROR ("no constant pool");
- g_string_free (string, TRUE);
- return NULL;
+ goto error;
}
id = type == 8 ? swfdec_bits_get_u8 (&bits) : swfdec_bits_get_u16 (&bits);
s = swfdec_constant_pool_get (parser->constant_pool, id);
if (!s) {
SWFDEC_ERROR ("constant pool size too small");
- g_string_free (string, TRUE);
- return NULL;
+ goto error;
}
g_string_append_c (string, '"');
g_string_append (string, s);
@@ -125,10 +121,14 @@ swfdec_debugger_print_push (ScriptParser
break;
default:
SWFDEC_ERROR ("Push: type %u not implemented", type);
- return NULL;
+ goto error;
}
}
return g_string_free (string, FALSE);
+
+error:
+ g_string_free (string, TRUE);
+ return "erroneous action Push";
}
/* NB: constant pool actions are special in that they are called at init time */
@@ -140,15 +140,14 @@ swfdec_debugger_add_command (gconstpoint
SwfdecDebuggerCommand command;
command.code = bytecode;
- if (action == 0x96) {
- /* PUSH */
+ if (action == SWFDEC_AS_ACTION_PUSH) {
command.description = swfdec_debugger_print_push (parser, data, len);
} else {
command.description = swfdec_script_print_action (action, data, len);
}
+ g_assert (command.description != NULL);
g_array_append_val (parser->commands, command);
- if (action == 0x88) {
- /* constant pool */
+ if (action == SWFDEC_AS_ACTION_CONSTANT_POOL) {
if (parser->constant_pool)
swfdec_constant_pool_free (parser->constant_pool);
parser->constant_pool = swfdec_constant_pool_new_from_action (data, len);
diff-tree f47891d0c97c9679dc4234c83866948ace3d1d50 (from 36576d269d6927d4d2403f98c5dce4e0998b805f)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 14:06:09 2007 +0200
return a valid string in _print_action () all the time, never return NULL
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index f5fd334..06b9d75 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -129,15 +129,16 @@ swfdec_script_print_action (guint action
if (action & 0x80) {
if (spec->print == NULL) {
- SWFDEC_ERROR ("action %u %s has no print statement",
- action, spec->name ? spec->name : "Unknown");
- return NULL;
+ SWFDEC_ERROR ("action %u 0x%02X %s has no print statement",
+ action, action, spec->name ? spec->name : "Unknown");
+ return g_strdup_printf ("erroneous action %s",
+ spec->name ? spec->name : "Unknown");
}
return spec->print (action, data, len);
} else {
if (spec->name == NULL) {
SWFDEC_ERROR ("action %u is unknown", action);
- return NULL;
+ return g_strdup_printf ("unknown Action 0x%02X", action);
}
return g_strdup (spec->name);
}
diff-tree 36576d269d6927d4d2403f98c5dce4e0998b805f (from 0a383b0939aff7f9b7b4d6922e53645f1151874f)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:52:00 2007 +0200
implement calling valueOf when converting to number
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 4731c97..889fceb 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -99,6 +99,7 @@ const char *swfdec_as_strings[] = {
SWFDEC_AS_CONSTANT_STRING ("function"),
SWFDEC_AS_CONSTANT_STRING ("object"),
SWFDEC_AS_CONSTANT_STRING ("toString"),
+ SWFDEC_AS_CONSTANT_STRING ("valueOf"),
/* add more here */
NULL
};
@@ -204,8 +205,15 @@ swfdec_as_value_to_number (SwfdecAsConte
return NAN;
}
case SWFDEC_TYPE_AS_ASOBJECT:
- SWFDEC_ERROR ("FIXME");
- return NAN;
+ {
+ SwfdecAsValue ret;
+ swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_VALUEOF,
+ 0, NULL, &ret);
+ if (SWFDEC_AS_VALUE_IS_NUMBER (&ret))
+ return SWFDEC_AS_VALUE_GET_NUMBER (&ret);
+ else
+ return NAN;
+ }
default:
g_assert_not_reached ();
return NAN;
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index b114bae..2cfe796 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -166,6 +166,7 @@ extern const char *swfdec_as_strings[];
#define SWFDEC_AS_STR_FUNCTION SWFDEC_AS_STR_CONSTANT(66)
#define SWFDEC_AS_STR_OBJECT SWFDEC_AS_STR_CONSTANT(67)
#define SWFDEC_AS_STR_TOSTRING SWFDEC_AS_STR_CONSTANT(68)
+#define SWFDEC_AS_STR_VALUEOF SWFDEC_AS_STR_CONSTANT(69)
/* all existing actions */
typedef enum {
diff-tree 0a383b0939aff7f9b7b4d6922e53645f1151874f (from 7b3c6b319a51bf19205f6314d9b171243f9af88a)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:51:41 2007 +0200
use current scale not user set scale when computing click area
diff --git a/player/swfdec_debug_widget.c b/player/swfdec_debug_widget.c
index 4c7ebcc..953b918 100644
--- a/player/swfdec_debug_widget.c
+++ b/player/swfdec_debug_widget.c
@@ -60,7 +60,7 @@ swfdec_debug_widget_button_press (GtkWid
return FALSE;
if (event->button == 1 && swfdec_gtk_widget_get_interactive (widget)) {
- double scale = swfdec_gtk_widget_get_scale (widget);
+ double scale = swfdec_gtk_widget_get_current_scale (widget);
SwfdecPlayer *player = swfdec_gtk_widget_get_player (widget);
switch (event->type) {
case GDK_BUTTON_PRESS:
diff-tree 7b3c6b319a51bf19205f6314d9b171243f9af88a (from 096cfd1d49808ca78c06a2db0f3fe4ac9cd94dc6)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:39:08 2007 +0200
remove debugging g_print
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index e88c30d..e38d9ba 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -386,7 +386,6 @@ start:
pc = frame->pc;
while (TRUE) {
- g_print ("pc is %p\n", pc);
if (pc == endpc) {
swfdec_as_context_return (context);
goto start;
diff-tree 096cfd1d49808ca78c06a2db0f3fe4ac9cd94dc6 (from 605184459c5be15046a75e42ef912f0d12a7ecf6)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:38:28 2007 +0200
copy the name of the calling script
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 36db616..ee6c8ca 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -104,11 +104,12 @@ swfdec_as_frame_new (SwfdecAsObject *thi
if (!swfdec_as_context_use_mem (context, size))
return NULL;
frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
- SWFDEC_DEBUG ("new frame");
swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
frame->next = context->frame;
context->frame = frame;
frame->script = swfdec_script_ref (script);
+ frame->function_name = script->name;
+ SWFDEC_DEBUG ("new frame for function %s", frame->function_name);
frame->pc = script->buffer->data;
frame->stack = stack;
frame->scope = thisp;
diff-tree 605184459c5be15046a75e42ef912f0d12a7ecf6 (from 3c696bc51ec288dfe931bc23b1e297d4b7e169da)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:38:16 2007 +0200
break on 0 action before invoking the debugger
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 46b8889..e88c30d 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -386,6 +386,7 @@ start:
pc = frame->pc;
while (TRUE) {
+ g_print ("pc is %p\n", pc);
if (pc == endpc) {
swfdec_as_context_return (context);
goto start;
@@ -395,6 +396,13 @@ start:
goto error;
}
+ /* decode next action */
+ action = *pc;
+ if (action == 0) {
+ swfdec_as_context_return (context);
+ goto start;
+ }
+ /* invoke debugger if there is one */
if (step) {
frame->pc = pc;
(* step) (context);
@@ -403,11 +411,8 @@ start:
goto start;
}
}
- /* decode next action */
- action = *pc;
+ /* prepare action */
spec = swfdec_as_actions + action;
- if (action == 0)
- break;
if (action & 0x80) {
if (pc + 2 >= endpc) {
SWFDEC_ERROR ("action %u length value out of range", action);
@@ -445,6 +450,7 @@ start:
#ifndef G_DISABLE_ASSERT
check = (spec->add >= 0 && spec->remove >= 0) ? stack->cur + spec->add - spec->remove : NULL;
#endif
+ /* execute action */
spec->exec[version] (context, action, data, len);
if (frame == context->frame) {
#ifndef G_DISABLE_ASSERT
diff-tree 3c696bc51ec288dfe931bc23b1e297d4b7e169da (from 847c11c34cc23a33097931e2b4022ba1c585b94b)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 13:22:18 2007 +0200
refacotr function calls and return value handling
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 9c6e56e..747b071 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -313,12 +313,41 @@ swfdec_as_object_run (SwfdecAsObject *ob
swfdec_as_context_run (object->context);
}
+/**
+ * swfdec_as_object_call:
+ * @object: a #SwfdecAsObject
+ * @name: garbage-collected string naming the function to call.
+ * @argc: number of arguments to provide to function
+ * @argv: arguments or %NULL when @argc is 0
+ * @return_value: location to take the return value of the call or %NULL to
+ * ignore the return value.
+ *
+ * Calls the function named @name on the given object. This function is
+ * essentially equal to the folloeing Actionscript code:
+ * <informalexample><programlisting>
+ * @return_value = @object. at name (@argv[0], ..., @argv[argc-1]);
+ * </programlisting></informalexample>
+ **/
void
-swfdec_as_object_call (SwfdecAsObject *object, const char *name, guint argc, SwfdecAsValue *argv)
+swfdec_as_object_call (SwfdecAsObject *object, const char *name, guint argc,
+ SwfdecAsValue *argv, SwfdecAsValue *return_value)
{
+ SwfdecAsValue tmp;
+ SwfdecAsFunction *fun;
+
g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
g_return_if_fail (name != NULL);
g_return_if_fail (argc == 0 || argv != NULL);
+
+ if (return_value)
+ SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
+ swfdec_as_object_get (object, name, &tmp);
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (&tmp))
+ return;
+ fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&tmp);
+ if (!SWFDEC_IS_AS_FUNCTION (fun))
+ return;
+ swfdec_as_function_call (fun, object, argc, argv, return_value ? return_value : &tmp);
}
gboolean
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index b843011..0876bbb 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -130,7 +130,8 @@ gboolean swfdec_as_object_has_function (
void swfdec_as_object_call (SwfdecAsObject * object,
const char * name,
guint argc,
- SwfdecAsValue * argv);
+ SwfdecAsValue * argv,
+ SwfdecAsValue * return_value);
G_END_DECLS
#endif
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index ee8c403..4731c97 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -98,6 +98,7 @@ const char *swfdec_as_strings[] = {
SWFDEC_AS_CONSTANT_STRING ("movieclip"),
SWFDEC_AS_CONSTANT_STRING ("function"),
SWFDEC_AS_CONSTANT_STRING ("object"),
+ SWFDEC_AS_CONSTANT_STRING ("toString"),
/* add more here */
NULL
};
@@ -138,8 +139,15 @@ swfdec_as_value_to_string (SwfdecAsConte
return ret;
}
case SWFDEC_TYPE_AS_ASOBJECT:
- SWFDEC_ERROR ("FIXME");
- return SWFDEC_AS_STR_OBJECT_OBJECT;
+ {
+ SwfdecAsValue ret;
+ swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_TOSTRING,
+ 0, NULL, &ret);
+ if (SWFDEC_AS_VALUE_IS_STRING (&ret))
+ return SWFDEC_AS_VALUE_GET_STRING (&ret);
+ else
+ return SWFDEC_AS_STR_OBJECT_OBJECT;
+ }
default:
g_assert_not_reached ();
return SWFDEC_AS_STR_EMPTY;
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index a65772a..b114bae 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -165,6 +165,7 @@ extern const char *swfdec_as_strings[];
#define SWFDEC_AS_STR_MOVIECLIP SWFDEC_AS_STR_CONSTANT(65)
#define SWFDEC_AS_STR_FUNCTION SWFDEC_AS_STR_CONSTANT(66)
#define SWFDEC_AS_STR_OBJECT SWFDEC_AS_STR_CONSTANT(67)
+#define SWFDEC_AS_STR_TOSTRING SWFDEC_AS_STR_CONSTANT(68)
/* all existing actions */
typedef enum {
diff --git a/libswfdec/swfdec_button_movie.c b/libswfdec/swfdec_button_movie.c
index 15267b6..a16a4f9 100644
--- a/libswfdec/swfdec_button_movie.c
+++ b/libswfdec/swfdec_button_movie.c
@@ -109,7 +109,7 @@ swfdec_button_movie_execute (SwfdecButto
swfdec_event_list_execute (movie->button->events,
SWFDEC_AS_OBJECT (SWFDEC_MOVIE (movie)->parent), condition, 0);
name = swfdec_button_condition_get_name (condition);
- swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL, NULL);
}
#define CONTENT_IN_FRAME(content, frame) \
diff --git a/libswfdec/swfdec_connection.c b/libswfdec/swfdec_connection.c
index d55c916..e10e53b 100644
--- a/libswfdec/swfdec_connection.c
+++ b/libswfdec/swfdec_connection.c
@@ -76,7 +76,7 @@ swfdec_connection_onstatus (SwfdecConnec
}
SWFDEC_AS_VALUE_SET_OBJECT (&value, info);
swfdec_as_object_unroot (info);
- swfdec_as_object_call (SWFDEC_AS_OBJECT (conn), SWFDEC_AS_STR_STATUS, 1, &value);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (conn), SWFDEC_AS_STR_STATUS, 1, &value, NULL);
}
SwfdecConnection *
diff --git a/libswfdec/swfdec_listener.c b/libswfdec/swfdec_listener.c
index b4495e7..b2021f0 100644
--- a/libswfdec/swfdec_listener.c
+++ b/libswfdec/swfdec_listener.c
@@ -135,7 +135,7 @@ swfdec_listener_execute (SwfdecListener
listener->entries[i].removed = FALSE;
}
listener->entries[i].blocked_by = NULL;
- swfdec_as_object_call (obj, event, 0, NULL);
+ swfdec_as_object_call (obj, event, 0, NULL, NULL);
}
}
}
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 3b6a726..e627130 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -410,7 +410,7 @@ swfdec_movie_execute_script (SwfdecMovie
}
name = swfdec_event_type_get_name (condition);
if (name != NULL)
- swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL, NULL);
}
static void
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 4fa1a32..fc19af2 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -46,7 +46,7 @@ swfdec_net_stream_onstatus (SwfdecNetStr
swfdec_as_object_set (object, SWFDEC_AS_STR_LEVEL, &val);
SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
- swfdec_as_object_call (SWFDEC_AS_OBJECT (stream), SWFDEC_AS_STR_ON_STATUS, 1, &val);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (stream), SWFDEC_AS_STR_ON_STATUS, 1, &val, NULL);
}
static void swfdec_net_stream_update_playing (SwfdecNetStream *stream);
@@ -113,7 +113,7 @@ swfdec_net_stream_video_goto (SwfdecNetS
SWFDEC_ERROR ("could not parse data tag");
} else {
swfdec_as_object_call (SWFDEC_AS_OBJECT (stream),
- SWFDEC_AS_VALUE_GET_STRING (&name), 1, &value);
+ SWFDEC_AS_VALUE_GET_STRING (&name), 1, &value, NULL);
}
}
}
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
index c931c6b..057c64c 100644
--- a/libswfdec/swfdec_xml.c
+++ b/libswfdec/swfdec_xml.c
@@ -47,7 +47,7 @@ swfdec_xml_ondata (SwfdecXml *xml)
} else {
SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
}
- swfdec_as_object_call (SWFDEC_AS_OBJECT (xml), SWFDEC_AS_STR_ON_DATA, 1, &val);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (xml), SWFDEC_AS_STR_ON_DATA, 1, &val, NULL);
}
static void
diff-tree 847c11c34cc23a33097931e2b4022ba1c585b94b (from 19645bbd08100a4684ace9256ed47edbfc629aa8)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 12:27:41 2007 +0200
rework handling of return values
function calls now take a pointer to a return value. That value is
set to UNDEFINED right now and can then be overwritten by subsequent
return actions.
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 185ae0a..46b8889 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -387,7 +387,7 @@ start:
while (TRUE) {
if (pc == endpc) {
- swfdec_as_context_return (context, NULL);
+ swfdec_as_context_return (context);
goto start;
}
if (pc < startpc || pc >= endpc) {
@@ -471,19 +471,12 @@ error:
}
void
-swfdec_as_context_return (SwfdecAsContext *context, SwfdecAsValue *retval)
+swfdec_as_context_return (SwfdecAsContext *context)
{
g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
g_return_if_fail (context->frame != NULL);
- g_return_if_fail (retval == NULL || SWFDEC_IS_AS_VALUE (retval));
context->frame = context->frame->next;
- swfdec_as_stack_ensure_left (context->frame->stack, 1);
- if (retval) {
- *swfdec_as_stack_push (context->frame->stack) = *retval;
- } else {
- SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_push (context->frame->stack));
- }
}
void
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index b4b2777..ca1b818 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -90,8 +90,7 @@ void swfdec_as_string_mark (const char
void swfdec_as_context_gc (SwfdecAsContext * context);
void swfdec_as_context_run (SwfdecAsContext * context);
-void swfdec_as_context_return (SwfdecAsContext * context,
- SwfdecAsValue * retval);
+void swfdec_as_context_return (SwfdecAsContext * context);
void swfdec_as_context_trace (SwfdecAsContext * context,
const char * string);
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 8d806bf..a89c7ee 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -40,6 +40,7 @@ struct _SwfdecAsFrame {
SwfdecAsFrame * next; /* next frame (FIXME: keep a list in the context instead?) */
char * function_name; /* name of function */
+ SwfdecAsValue * return_value; /* pointer to where to store the return value */
/* normal execution */
SwfdecScript * script; /* script being executed */
SwfdecAsObject * scope; /* scope object coming after this: an Object */
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 65540d2..653efea 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -107,13 +107,16 @@ swfdec_as_function_new_native (SwfdecAsC
}
void
-swfdec_as_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp, guint n_args)
+swfdec_as_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp, guint n_args,
+ SwfdecAsValue *args, SwfdecAsValue *return_value)
{
SwfdecAsContext *context;
SwfdecAsFrame *frame;
g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function));
g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp));
+ g_return_if_fail (n_args == 0 || args != NULL);
+ g_return_if_fail (return_value != NULL);
context = thisp->context;
if (context->frame) {
@@ -122,9 +125,9 @@ swfdec_as_function_call (SwfdecAsFunctio
} else {
n_args = 0;
}
+ SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
/* now do different things depending on if we're a native function or not */
if (function->native) {
- SwfdecAsValue retval = { 0, };
if (n_args < function->min_args) {
SwfdecAsStack *stack = context->frame->stack;
if (n_args == 0) {
@@ -139,10 +142,11 @@ swfdec_as_function_call (SwfdecAsFunctio
frame = swfdec_as_frame_new_native (thisp);
g_assert (function->name);
frame->function_name = function->name;
- function->native (context, thisp, n_args, NULL, &retval);
- swfdec_as_context_return (context, &retval);
+ function->native (context, thisp, n_args, args, return_value);
+ swfdec_as_context_return (context);
} else {
frame = swfdec_as_frame_new (thisp, function->script);
+ frame->return_value = return_value;
/* FIXME: do the preloading here */
}
}
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index d39c645..77ca819 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -66,7 +66,9 @@ SwfdecAsFunction * swfdec_as_function_ne
void swfdec_as_function_call (SwfdecAsFunction * function,
SwfdecAsObject * thisp,
- guint n_args);
+ guint n_args,
+ SwfdecAsValue * args,
+ SwfdecAsValue * return_value);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index cc2bf34..11ae005 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -658,6 +658,8 @@ swfdec_action_call (SwfdecAsContext *cx,
SwfdecAsFunction *fun;
SwfdecAsObject *thisp;
SwfdecAsFrame *frame = cx->frame;
+ SwfdecAsValue retval;
+ guint i;
if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 1)) ||
!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 2)))
@@ -667,7 +669,20 @@ swfdec_action_call (SwfdecAsContext *cx,
goto error;
thisp = SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (frame->stack, 2));
swfdec_as_stack_pop_n (frame->stack, 2);
- swfdec_as_function_call (fun, thisp, n_args);
+ /* swap arguments on the stack */
+ /* FIXME: can we somehow keep this order please, it might be interesting for debuggers */
+ for (i = 0; i < n_args / 2; i++) {
+ SwfdecAsValue tmp = *swfdec_as_stack_peek (frame->stack, i + 1);
+ *swfdec_as_stack_peek (frame->stack, i + 1) = *swfdec_as_stack_peek (frame->stack, n_args - i);
+ *swfdec_as_stack_peek (frame->stack, n_args - i) = tmp;
+ }
+ swfdec_as_function_call (fun, thisp, n_args, swfdec_as_stack_peek (frame->stack, n_args), &retval);
+ if (n_args) {
+ swfdec_as_stack_pop_n (frame->stack, n_args - 1);
+ *swfdec_as_stack_peek (frame->stack, 1) = retval;
+ } else {
+ *swfdec_as_stack_push (frame->stack) = retval;
+ }
return;
error:
diff-tree 19645bbd08100a4684ace9256ed47edbfc629aa8 (from 63635ba4c29a8ecb3de4314f4586ed85c90266d7)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 11:28:47 2007 +0200
implement RandomNumber action
Also add a GRand to SwfdecAsContext so we can set/get the seed to reproduce
stuff.
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index d8a0859..185ae0a 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -266,6 +266,7 @@ swfdec_as_context_dispose (GObject *obje
g_assert (g_hash_table_size (context->objects) == 0);
g_hash_table_destroy (context->objects);
g_hash_table_destroy (context->strings);
+ g_rand_free (context->rand);
G_OBJECT_CLASS (swfdec_as_context_parent_class)->dispose (object);
}
@@ -305,6 +306,7 @@ swfdec_as_context_init (SwfdecAsContext
(char *) swfdec_as_strings[i]);
}
context->global = swfdec_as_object_new (context);
+ context->rand = g_rand_new ();
}
/*** STRINGS ***/
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index e75f729..b4b2777 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -48,6 +48,7 @@ struct _SwfdecAsContext {
SwfdecAsContextState state; /* our current state */
SwfdecAsObject * global; /* the global object */
+ GRand * rand; /* random number generator */
/* bookkeeping for GC */
gsize memory; /* memory currently in use */
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 9e052c4..cc2bf34 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -981,23 +981,22 @@ swfdec_action_push_duplicate (SwfdecAsCo
*swfdec_as_stack_push (cx->frame->stack) = *swfdec_as_stack_peek (cx->frame->stack, 1);
}
-#if 0
static void
swfdec_action_random_number (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- gint32 max, result;
+ gint32 max;
+ SwfdecAsValue *val;
- if (!JS_ValueToECMAInt32 (cx, cx->fp->sp[-1], &max))
- return JS_FALSE;
+ val = swfdec_as_stack_peek (cx->frame->stack, 1);
+ max = swfdec_as_value_to_integer (cx, val);
if (max <= 0)
- result = 0;
+ SWFDEC_AS_VALUE_SET_NUMBER (val, 0);
else
- result = g_random_int_range (0, max);
-
- return JS_NewNumberValue(cx, result, &cx->fp->sp[-1]);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, g_rand_int_range (cx->rand, 0, max));
}
+#if 0
static void
swfdec_action_old_compare (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
@@ -2159,8 +2158,10 @@ const SwfdecActionSpec swfdec_as_actions
[0x2a] = { "Throw", NULL },
[0x2b] = { "Cast", NULL },
[0x2c] = { "Implements", NULL },
+#endif
/* version 4 */
[0x30] = { "RandomNumber", NULL, 1, 1, { NULL, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number } },
+#if 0
[0x31] = { "MBStringLength", NULL },
[0x32] = { "CharToAscii", NULL },
[0x33] = { "AsciiToChar", NULL },
diff-tree 63635ba4c29a8ecb3de4314f4586ed85c90266d7 (from d0b2d60131cc86f9bbeae1b75978198c607c69c2)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 11:18:04 2007 +0200
implement Greater and Less2 actions
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index e95796e..9e052c4 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -797,48 +797,45 @@ swfdec_action_add2 (SwfdecAsContext *cx,
}
}
-#if 0
static void
swfdec_action_new_comparison_6 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- jsval lval, rval;
double d, d2;
- rval = cx->fp->sp[-1];
- lval = cx->fp->sp[-2];
- cx->fp->sp--;
- d = swfdec_value_to_number (cx, lval);
- d2 = swfdec_value_to_number (cx, rval);
+ d2 = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx->frame->stack, 1));
+ d = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx->frame->stack, 2));
+ swfdec_as_stack_pop (cx->frame->stack);
if (action == 0x48)
- cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d < d2);
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), d < d2);
else
- cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d > d2);
- return JS_TRUE;
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), d > d2);
}
static void
swfdec_action_new_comparison_7 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- jsval lval, rval;
+ SwfdecAsValue *lval, *rval;
- rval = cx->fp->sp[-1];
- lval = cx->fp->sp[-2];
- cx->fp->sp--;
- if (JSVAL_IS_VOID (rval) || JSVAL_IS_VOID (lval)) {
- cx->fp->sp[-1] = JSVAL_VOID;
- } else if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {
- int comp = JS_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval));
- cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? comp < 0 : comp > 0);
+ rval = swfdec_as_stack_peek (cx->frame->stack, 1);
+ lval = swfdec_as_stack_peek (cx->frame->stack, 2);
+ if (SWFDEC_AS_VALUE_IS_UNDEFINED (rval) || SWFDEC_AS_VALUE_IS_UNDEFINED (lval)) {
+ swfdec_as_stack_pop (cx->frame->stack);
+ SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx->frame->stack, 1));
+ } else if (SWFDEC_AS_VALUE_IS_STRING (rval) || SWFDEC_AS_VALUE_IS_STRING (lval)) {
+ int comp = strcmp (SWFDEC_AS_VALUE_GET_STRING (rval), SWFDEC_AS_VALUE_GET_STRING (lval));
+ swfdec_as_stack_pop (cx->frame->stack);
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), action == 0x48 ? comp < 0 : comp > 0);
} else {
double d, d2;
- if (!JS_ValueToNumber(cx, lval, &d) ||
- !JS_ValueToNumber(cx, rval, &d2))
- return JS_FALSE;
- cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? d < d2 : d > d2);
+ d2 = swfdec_as_value_to_number (cx, rval);
+ d = swfdec_as_value_to_number (cx, lval);
+ swfdec_as_stack_pop (cx->frame->stack);
+ if (action == 0x48)
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), d < d2);
+ else
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), d > d2);
}
- return JS_TRUE;
}
-#endif
static void
swfdec_action_not_4 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
@@ -2191,9 +2188,7 @@ const SwfdecActionSpec swfdec_as_actions
[0x46] = { "Enumerate", NULL },
#endif
[SWFDEC_AS_ACTION_ADD2] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2, swfdec_action_add2, swfdec_action_add2 } },
-#if 0
- [0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
-#endif
+ [SWFDEC_AS_ACTION_LESS2] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
[SWFDEC_AS_ACTION_EQUALS2] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
[SWFDEC_AS_ACTION_TO_NUMBER] = { "ToNumber", NULL, 1, 1, { NULL, NULL, swfdec_action_to_number, swfdec_action_to_number, swfdec_action_to_number } },
[SWFDEC_AS_ACTION_TO_STRING] = { "ToString", NULL, 1, 1, { NULL, NULL, swfdec_action_to_string, swfdec_action_to_string, swfdec_action_to_string } },
@@ -2218,13 +2213,15 @@ const SwfdecActionSpec swfdec_as_actions
[0x65] = { "BitURShift", NULL, 2, 1, { NULL, NULL, swfdec_action_shift, swfdec_action_shift, swfdec_action_shift } },
/* version 6 */
[0x66] = { "StrictEquals", NULL },
- [0x67] = { "Greater", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
- [0x68] = { "StringGreater", NULL },
+#endif
+ [SWFDEC_AS_ACTION_GREATER] = { "Greater", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
+ [SWFDEC_AS_ACTION_STRING_GREATER] = { "StringGreater", NULL },
/* version 7 */
+#if 0
[0x69] = { "Extends", NULL, 2, 0, { NULL, NULL, NULL, NULL, swfdec_action_extends } },
+#endif
/* version 3 */
-#endif
[SWFDEC_AS_ACTION_GOTO_FRAME] = { "GotoFrame", swfdec_action_print_goto_frame, 0, 0, { swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame } },
#if 0
[0x83] = { "GetURL", swfdec_action_print_get_url, 0, 0, { swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url } },
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 10f3a9c..a65772a 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -243,7 +243,7 @@ typedef enum {
SWFDEC_AS_ACTION_BIT_URSHIFT = 0x65,
SWFDEC_AS_ACTION_STRICT_EQUALS = 0x66,
SWFDEC_AS_ACTION_GREATER = 0x67,
- SWFDEC_AS_ACTION_STRING_FREATER = 0x68,
+ SWFDEC_AS_ACTION_STRING_GREATER = 0x68,
SWFDEC_AS_ACTION_EXTENDS = 0x69,
SWFDEC_AS_ACTION_GOTO_FRAME = 0x81,
SWFDEC_AS_ACTION_GET_URL = 0x83,
diff-tree d0b2d60131cc86f9bbeae1b75978198c607c69c2 (from 5ff1c3070d3f85f152c6a1d4045904c3ced10266)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 11:07:50 2007 +0200
implement Equals2
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7dcd442..e95796e 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1031,57 +1031,58 @@ swfdec_action_old_compare (SwfdecAsConte
}
return JS_TRUE;
}
+#endif
static void
swfdec_action_equals2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- jsval rval, lval;
- int ltag, rtag;
- void cond;
-
- rval = cx->fp->sp[-1];
- lval = cx->fp->sp[-2];
- ltag = JSVAL_TAG(lval);
- rtag = JSVAL_TAG(rval);
- if (ltag == rtag) {
- if (ltag == JSVAL_STRING) {
- cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0;
- } else if (ltag == JSVAL_DOUBLE) {
- cond = *JSVAL_TO_DOUBLE(lval) == *JSVAL_TO_DOUBLE(rval);
- } else {
- cond = lval == rval;
+ SwfdecAsValue *rval, *lval;
+ SwfdecAsType ltype, rtype;
+ 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_TYPE_AS_UNDEFINED:
+ case SWFDEC_TYPE_AS_NULL:
+ cond = TRUE;
+ break;
+ case SWFDEC_TYPE_AS_BOOLEAN:
+ cond = SWFDEC_AS_VALUE_GET_BOOLEAN (lval) == SWFDEC_AS_VALUE_GET_BOOLEAN (rval);
+ break;
+ case SWFDEC_TYPE_AS_NUMBER:
+ cond = SWFDEC_AS_VALUE_GET_NUMBER (lval) == SWFDEC_AS_VALUE_GET_NUMBER (rval);
+ break;
+ case SWFDEC_TYPE_AS_STRING:
+ cond = SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval);
+ break;
+ case SWFDEC_TYPE_AS_ASOBJECT:
+ cond = SWFDEC_AS_VALUE_GET_OBJECT (lval) == SWFDEC_AS_VALUE_GET_OBJECT (rval);
+ break;
+ default:
+ g_assert_not_reached ();
+ cond = FALSE;
+ break;
}
} else {
- if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {
- cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval));
- } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {
- cond = JS_FALSE;
+ if (ltype == SWFDEC_TYPE_AS_UNDEFINED || ltype == SWFDEC_TYPE_AS_NULL) {
+ cond = (rtype == SWFDEC_TYPE_AS_UNDEFINED || rtype == SWFDEC_TYPE_AS_NULL);
+ } else if (rtype == SWFDEC_TYPE_AS_UNDEFINED || rtype == SWFDEC_TYPE_AS_NULL) {
+ cond = FALSE;
} else {
- if (ltag == JSVAL_OBJECT) {
- if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(lval), 0, &lval))
- return JS_FALSE;
- ltag = JSVAL_TAG(lval);
- } else if (rtag == JSVAL_OBJECT) {
- if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(rval), 0, &rval))
- return JS_FALSE;
- rtag = JSVAL_TAG(rval);
- }
- if (ltag == JSVAL_STRING && rtag == JSVAL_STRING) {
- cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0;
- } else {
- double d, d2;
- if (!JS_ValueToNumber (cx, lval, &d) ||
- !JS_ValueToNumber (cx, rval, &d2))
- return JS_FALSE;
- cond = d == d2;
- }
+ 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;
}
}
- cx->fp->sp--;
- cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond);
- return JS_TRUE;
+ swfdec_as_stack_pop (cx->frame->stack);
+ SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx->frame->stack, 1), cond);
}
-#endif
static void
swfdec_action_set_target (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
@@ -2192,8 +2193,8 @@ const SwfdecActionSpec swfdec_as_actions
[SWFDEC_AS_ACTION_ADD2] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2, swfdec_action_add2, swfdec_action_add2 } },
#if 0
[0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
- [0x49] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
#endif
+ [SWFDEC_AS_ACTION_EQUALS2] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
[SWFDEC_AS_ACTION_TO_NUMBER] = { "ToNumber", NULL, 1, 1, { NULL, NULL, swfdec_action_to_number, swfdec_action_to_number, swfdec_action_to_number } },
[SWFDEC_AS_ACTION_TO_STRING] = { "ToString", NULL, 1, 1, { NULL, NULL, swfdec_action_to_string, swfdec_action_to_string, swfdec_action_to_string } },
[SWFDEC_AS_ACTION_PUSH_DUPLICATE] = { "PushDuplicate", NULL, 1, 2, { NULL, NULL, swfdec_action_push_duplicate, swfdec_action_push_duplicate, swfdec_action_push_duplicate } },
diff-tree 5ff1c3070d3f85f152c6a1d4045904c3ced10266 (from 75d5878407131d54858da7a2443c9ff5e793c86c)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 10:54:08 2007 +0200
implement Increment and Decrement
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index b876331..7dcd442 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -882,27 +882,25 @@ swfdec_action_if (SwfdecAsContext *cx, g
cx->frame->pc += 5 + GINT16_FROM_LE (*((gint16*) data));
}
-#if 0
static void
swfdec_action_decrement (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- double d;
+ SwfdecAsValue *val;
- d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
- d--;
- return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
+ val = swfdec_as_stack_peek (cx->frame->stack, 1);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (cx, val) + 1);
}
static void
swfdec_action_increment (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- double d;
+ SwfdecAsValue *val;
- d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
- d++;
- return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
+ val = swfdec_as_stack_peek (cx->frame->stack, 1);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (cx, val) + 1);
}
+#if 0
static void
swfdec_action_get_url (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
@@ -2202,10 +2200,8 @@ const SwfdecActionSpec swfdec_as_actions
[SWFDEC_AS_ACTION_SWAP] = { "Swap", NULL, 2, 2, { NULL, NULL, swfdec_action_swap, swfdec_action_swap, swfdec_action_swap } },
[SWFDEC_AS_ACTION_GET_MEMBER] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
[SWFDEC_AS_ACTION_SET_MEMBER] = { "SetMember", NULL, 3, 0, { NULL, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member } },
-#if 0
- [0x50] = { "Increment", NULL, 1, 1, { NULL, NULL, swfdec_action_increment, swfdec_action_increment, swfdec_action_increment } },
- [0x51] = { "Decrement", NULL, 1, 1, { NULL, NULL, swfdec_action_decrement, swfdec_action_decrement, swfdec_action_decrement } },
-#endif
+ [SWFDEC_AS_ACTION_INCREMENT] = { "Increment", NULL, 1, 1, { NULL, NULL, swfdec_action_increment, swfdec_action_increment, swfdec_action_increment } },
+ [SWFDEC_AS_ACTION_DECREMENT] = { "Decrement", NULL, 1, 1, { NULL, NULL, swfdec_action_decrement, swfdec_action_decrement, swfdec_action_decrement } },
[SWFDEC_AS_ACTION_CALL_METHOD] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } },
#if 0
[0x53] = { "NewMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_new_method, swfdec_action_new_method, swfdec_action_new_method } },
diff-tree 75d5878407131d54858da7a2443c9ff5e793c86c (from 1f5c7b93200bf3416a9ebad2ef079f46348a76c6)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 10:51:22 2007 +0200
implement SetTarget and SetTarget2
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index da19217..36db616 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -57,6 +57,8 @@ swfdec_as_frame_mark (SwfdecAsObject *ob
swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->next));
swfdec_as_object_mark (frame->scope);
swfdec_as_object_mark (frame->var_object);
+ if (frame->target)
+ swfdec_as_object_mark (frame->target);
for (i = 0; i < frame->n_registers; i++) {
swfdec_as_value_mark (&frame->registers[i]);
}
@@ -143,24 +145,54 @@ swfdec_as_frame_new_native (SwfdecAsObje
SwfdecAsObject *
swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const SwfdecAsValue *variable)
{
- SwfdecAsObject *ret = NULL;
+ SwfdecAsObject *cur, *ret = NULL;
guint i;
g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
g_return_val_if_fail (SWFDEC_IS_AS_VALUE (variable), NULL);
+ cur = SWFDEC_AS_OBJECT (frame);
for (i = 0; i < 256 && frame != NULL; i++) {
- ret = swfdec_as_object_find_variable (frame->scope, variable);
- if (ret)
- break;
- if (!SWFDEC_IS_AS_FRAME (frame->scope))
+ if (!SWFDEC_IS_AS_FRAME (cur))
break;
- frame = SWFDEC_AS_FRAME (frame->scope);
+ ret = swfdec_as_object_find_variable (cur, variable);
+ if (ret)
+ return ret;
+ cur = SWFDEC_AS_FRAME (cur)->scope;
}
+ g_assert (cur);
if (i == 256) {
swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded");
return NULL;
}
+ /* we've walked the scope chain down until the last object now.
+ * The last 2 objects in the scope chain are the current target and the global object */
+ if (frame->target) {
+ ret = swfdec_as_object_find_variable (frame->target, variable);
+ } else {
+ ret = swfdec_as_object_find_variable (cur, variable);
+ }
+ if (ret)
+ return ret;
+ ret = swfdec_as_object_find_variable (cur->context->global, variable);
return ret;
}
+/**
+ * swfdec_as_frame_set_target:
+ * @frame: a #SwfdecAsFrame
+ * @target: the new object to use as target or %NULL to unset
+ *
+ * Sets the new target to be used in this @frame. The target is a legacy
+ * Actionscript concept that is similar to "with". If you don't have to,
+ * you shouldn't use this function.
+ **/
+void
+swfdec_as_frame_set_target (SwfdecAsFrame *frame, SwfdecAsObject *target)
+{
+ g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
+ g_return_if_fail (target == NULL || SWFDEC_IS_AS_OBJECT (target));
+
+ frame->target = target;
+}
+
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index c9d8b08..8d806bf 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -42,7 +42,8 @@ struct _SwfdecAsFrame {
char * function_name; /* name of function */
/* normal execution */
SwfdecScript * script; /* script being executed */
- SwfdecAsObject * scope; /* scope object coming after this or NULL */
+ SwfdecAsObject * scope; /* scope object coming after this: an Object */
+ SwfdecAsObject * target; /* target to use instead of last object in scope chain */
SwfdecAsObject * var_object; /* new variables go here */
SwfdecAsValue * registers; /* the registers */
guint n_registers; /* number of allocated registers */
@@ -66,6 +67,9 @@ SwfdecAsFrame * swfdec_as_frame_new_nati
SwfdecAsObject *swfdec_as_frame_find_variable (SwfdecAsFrame * frame,
const SwfdecAsValue * variable);
+void swfdec_as_frame_set_target (SwfdecAsFrame * frame,
+ SwfdecAsObject * target);
+
G_END_DECLS
#endif
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 3989186..b876331 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1083,65 +1083,43 @@ swfdec_action_equals2 (SwfdecAsContext *
cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond);
return JS_TRUE;
}
-
-static void
-swfdec_action_do_set_target (SwfdecAsContext *cx, JSObject *target)
-{
- JSObject *with;
-
- /* FIXME: this whole function stops working the moment it's used together
- * with With */
- with = js_NewObject(cx, &js_WithClass, target, cx->fp->scopeChain);
- if (!with)
- return JS_FALSE;
- cx->fp->scopeChain = with;
- return JS_TRUE;
-}
-
-static void
-swfdec_action_do_unset_target (SwfdecAsContext *cx)
-{
- if (JS_GetClass (cx->fp->scopeChain) != &js_WithClass) {
- SWFDEC_ERROR ("Cannot unset target: scope chain contains no with object");
- return JS_TRUE;
- }
- cx->fp->scopeChain = JS_GetParent (cx, cx->fp->scopeChain);
- return JS_TRUE;
-}
+#endif
static void
swfdec_action_set_target (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- jsval target;
-
if (!memchr (data, 0, len)) {
SWFDEC_ERROR ("SetTarget action does not specify a string");
- return JS_FALSE;
+ return;
}
- if (*data == '\0')
- return swfdec_action_do_unset_target (cx);
- target = swfdec_js_eval (cx, NULL, (const char *) data);
- if (!JSVAL_IS_OBJECT (target) || JSVAL_IS_NULL (target)) {
- SWFDEC_WARNING ("target is not an object");
- return JS_TRUE;
+ if (*data == '\0') {
+ swfdec_as_frame_set_target (cx->frame, NULL);
+ } else {
+ SwfdecAsValue target;
+ swfdec_as_context_eval (cx, NULL, (const char *) data, &target);
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (&target)) {
+ SWFDEC_WARNING ("target is not an object");
+ return;
+ }
+ /* FIXME: allow non-movieclips as targets? */
+ swfdec_as_frame_set_target (cx->frame, SWFDEC_AS_VALUE_GET_OBJECT (&target));
}
- return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (target));
}
static void
swfdec_action_set_target2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- jsval val;
-
- val = cx->fp->sp[-1];
- cx->fp->sp--;
- if (!JSVAL_IS_OBJECT (val) || JSVAL_IS_NULL (val)) {
+ SwfdecAsValue *val;
+ val = swfdec_as_stack_peek (cx->frame->stack, 1);
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (val)) {
SWFDEC_WARNING ("target is not an object");
- return JS_TRUE;
- }
- return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (val));
+ return;
+ }
+ /* FIXME: allow non-movieclips as targets? */
+ swfdec_as_frame_set_target (cx->frame, SWFDEC_AS_VALUE_GET_OBJECT (val));
}
+#if 0
static void
swfdec_action_start_drag (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
@@ -1858,17 +1836,19 @@ swfdec_action_print_store_register (guin
}
return g_strdup_printf ("StoreRegister %u", (guint) *data);
}
+#endif
static char *
swfdec_action_print_set_target (guint action, const guint8 *data, guint len)
{
if (!memchr (data, 0, len)) {
SWFDEC_ERROR ("SetTarget action does not specify a string");
- return JS_FALSE;
+ return NULL;
}
return g_strconcat ("SetTarget ", data, NULL);
}
+#if 0
static char *
swfdec_action_print_define_function (guint action, const guint8 *data, guint len)
{
@@ -2166,8 +2146,8 @@ const SwfdecActionSpec swfdec_as_actions
#endif
[SWFDEC_AS_ACTION_GET_VARIABLE] = { "GetVariable", NULL, 1, 1, { NULL, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable } },
[SWFDEC_AS_ACTION_SET_VARIABLE] = { "SetVariable", NULL, 2, 0, { NULL, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable } },
+ [SWFDEC_AS_ACTION_SET_TARGET2] = { "SetTarget2", NULL, 1, 0, { swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2 } },
#if 0
- [0x20] = { "SetTarget2", NULL, 1, 0, { swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2, swfdec_action_set_target2 } },
[0x21] = { "StringAdd", NULL, 2, 1, { NULL, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add } },
#endif
[0x22] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
@@ -2257,9 +2237,7 @@ const SwfdecActionSpec swfdec_as_actions
[SWFDEC_AS_ACTION_CONSTANT_POOL] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } },
/* version 3 */
[SWFDEC_AS_ACTION_WAIT_FOR_FRAME] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } },
-#if 0
- [0x8b] = { "SetTarget", swfdec_action_print_set_target, 0, 0, { swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target } },
-#endif
+ [SWFDEC_AS_ACTION_SET_TARGET] = { "SetTarget", swfdec_action_print_set_target, 0, 0, { swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target, swfdec_action_set_target } },
[SWFDEC_AS_ACTION_GOTO_LABEL] = { "GotoLabel", swfdec_action_print_goto_label, 0, 0, { swfdec_action_goto_label, swfdec_action_goto_label, swfdec_action_goto_label, swfdec_action_goto_label, swfdec_action_goto_label } },
#if 0
/* version 4 */
diff-tree 1f5c7b93200bf3416a9ebad2ef079f46348a76c6 (from bf5b82f30cd63edfe3e508e785583e6e4356cde9)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 12 10:51:08 2007 +0200
We have a global object now
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 9756fc9..d8a0859 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -225,6 +225,8 @@ swfdec_as_context_mark_roots (gpointer k
static void
swfdec_as_context_do_mark (SwfdecAsContext *context)
{
+ if (context->global)
+ swfdec_as_object_mark (context->global);
g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL);
}
@@ -302,6 +304,7 @@ swfdec_as_context_init (SwfdecAsContext
g_hash_table_insert (context->strings, (char *) swfdec_as_strings[i] + 1,
(char *) swfdec_as_strings[i]);
}
+ context->global = swfdec_as_object_new (context);
}
/*** STRINGS ***/
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 72f5ec1..e75f729 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -47,6 +47,7 @@ struct _SwfdecAsContext {
GObject object;
SwfdecAsContextState state; /* our current state */
+ SwfdecAsObject * global; /* the global object */
/* bookkeeping for GC */
gsize memory; /* memory currently in use */
More information about the Swfdec
mailing list