[Swfdec] Branch 'interpreter' - 2 commits - libswfdec/js
libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c
Benjamin Otte
company at kemper.freedesktop.org
Thu Jan 18 00:34:06 PST 2007
libswfdec/js/jsinterp.c | 1
libswfdec/js/jsinterp.h | 3 -
libswfdec/swfdec_js_movie.c | 3 -
libswfdec/swfdec_script.c | 100 ++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 100 insertions(+), 7 deletions(-)
New commits:
diff-tree c3f0eaf5706a0d972132a0ea4fcaff5aa79ec122 (from 3e6fcd37cb3157514beaf45cb90e2c68d2138b86)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 17 22:51:45 2007 +0100
add the SwfdecSCript to the stack frame
also, some more functions are implemented (like WaitForFrame, it needs this)
diff --git a/libswfdec/js/jsinterp.c b/libswfdec/js/jsinterp.c
index 1a45a77..1d15966 100644
--- a/libswfdec/js/jsinterp.c
+++ b/libswfdec/js/jsinterp.c
@@ -832,6 +832,7 @@ have_fun:
frame.varobj = NULL;
frame.callobj = frame.argsobj = NULL;
frame.script = script;
+ frame.swf = swf;
frame.fun = fun;
frame.argc = argc;
frame.argv = sp - argc;
diff --git a/libswfdec/js/jsinterp.h b/libswfdec/js/jsinterp.h
index d68957d..b22166d 100644
--- a/libswfdec/js/jsinterp.h
+++ b/libswfdec/js/jsinterp.h
@@ -54,7 +54,8 @@ struct JSStackFrame {
JSObject *callobj; /* lazily created Call object */
JSObject *argsobj; /* lazily created arguments object */
JSObject *varobj; /* variables object, where vars go */
- JSScript *script; /* script being interpreted */
+ JSScript *script; /* script being interpreted or NULL */
+ void *swf; /* SwfdecScript being executed if script is NULL */
JSFunction *fun; /* function being called or null */
JSObject *thisp; /* "this" pointer if in method */
uintN argc; /* actual argument count */
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 3d39a72..5b01510 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -29,7 +29,9 @@
/*** SUPPORT FUNCTIONS ***/
+#include "swfdec_decoder.h"
#include "swfdec_movie.h"
+#include "swfdec_root_movie.h"
static SwfdecMovie *
swfdec_action_get_target (JSContext *cx)
@@ -45,9 +47,91 @@ swfdec_action_stop (JSContext *cx, guint
SwfdecMovie *movie = swfdec_action_get_target (cx);
if (movie)
movie->stopped = TRUE;
+ else
+ SWFDEC_ERROR ("no movie to stop");
return JS_TRUE;
}
+static JSBool
+swfdec_action_play (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecMovie *movie = swfdec_action_get_target (cx);
+ if (movie)
+ movie->stopped = FALSE;
+ else
+ SWFDEC_ERROR ("no movie to play");
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_goto_frame (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecMovie *movie = swfdec_action_get_target (cx);
+ guint frame;
+
+ if (len != 2) {
+ SWFDEC_ERROR ("GotoFrame action length invalid (is %u, should be 2", len);
+ return JS_FALSE;
+ }
+ frame = GUINT16_FROM_LE (*((guint16 *) data));
+ if (movie) {
+ swfdec_movie_goto (movie, frame);
+ movie->stopped = TRUE;
+ } else {
+ SWFDEC_ERROR ("no movie to goto on");
+ }
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_wait_for_frame (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecMovie *movie = swfdec_action_get_target (cx);
+ guint frame, jump, loaded;
+
+ if (len != 3) {
+ SWFDEC_ERROR ("WaitForFrame action length invalid (is %u, should be 3", len);
+ return JS_TRUE;
+ }
+ if (movie == NULL) {
+ SWFDEC_ERROR ("no movie for WaitForFrame");
+ return JS_TRUE;
+ }
+
+ frame = GUINT16_FROM_LE (*((guint16 *) data));
+ jump = data[2];
+ if (SWFDEC_IS_ROOT_MOVIE (movie)) {
+ SwfdecDecoder *dec = SWFDEC_ROOT_MOVIE (movie->root)->decoder;
+ loaded = dec->frames_loaded;
+ g_assert (loaded <= movie->n_frames);
+ } else {
+ loaded = movie->n_frames;
+ }
+ if (loaded < frame) {
+ SwfdecScript *script = cx->fp->swf;
+ guint8 *pc = cx->fp->pc;
+ guint8 *endpc = script->buffer->data + script->buffer->length;
+
+ /* jump instructions */
+ g_assert (script);
+ do {
+ if (pc >= endpc)
+ break;
+ if (*pc & 0x80) {
+ if (pc + 2 >= endpc)
+ break;
+ pc += 3 + GUINT16_FROM_LE (*((guint16 *) (pc + 1)));
+ } else {
+ pc++;
+ }
+ } while (jump-- > 0);
+ cx->fp->pc = pc;
+ }
+ return JS_TRUE;
+}
+
+/*** PRINT FUNCTIONS ***/
+
static char *
swfdec_action_print_goto_frame (guint action, const guint8 *data, guint len)
{
@@ -93,7 +177,7 @@ static const SwfdecActionSpec actions[25
/* version 3 */
[0x04] = { "NextFrame", NULL },
[0x05] = { "PreviousFrame", NULL },
- [0x06] = { "Play", NULL },
+ [0x06] = { "Play", NULL, 0, 0, { swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play } },
[0x07] = { "Stop", NULL, 0, 0, { swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop } },
[0x08] = { "ToggleQuality", NULL },
[0x09] = { "StopSounds", NULL },
@@ -182,13 +266,13 @@ static const SwfdecActionSpec actions[25
[0x69] = { "Extends", NULL },
/* version 3 */
- [0x81] = { "GotoFrame", swfdec_action_print_goto_frame },
+ [0x81] = { "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 } },
[0x83] = { "GetURL", NULL },
/* version 5 */
[0x87] = { "StoreRegister", NULL },
[0x88] = { "ConstantPool", NULL },
/* version 3 */
- [0x8a] = { "WaitForFrame", swfdec_action_print_wait_for_frame },
+ [0x8a] = { "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 } },
[0x8b] = { "SetTarget", NULL },
[0x8c] = { "GotoLabel", NULL },
/* version 4 */
@@ -262,12 +346,14 @@ static gboolean
validate_action (guint action, const guint8 *data, guint len, gpointer script)
{
/* we might want to do stuff here for certain actions */
+#if 0
{
char *foo = swfdec_script_print_action (action, data, len);
if (foo == NULL)
return FALSE;
g_print ("%s\n", foo);
}
+#endif
return TRUE;
}
@@ -362,6 +448,7 @@ swfdec_script_interpret (SwfdecScript *s
/* set up the script */
startpc = pc = script->buffer->data;
endpc = startpc + script->buffer->length;
+ fp->pc = pc;
/* set up stack */
startsp = js_AllocStack (cx, STACKSIZE, &mark);
if (!startsp) {
@@ -426,7 +513,11 @@ swfdec_script_interpret (SwfdecScript *s
ok = spec->exec[version] (cx, action, data, len);
if (!ok)
goto out;
- pc = nextpc;
+ if (fp->pc == pc) {
+ fp->pc = pc = nextpc;
+ } else {
+ pc = fp->pc;
+ }
}
out:
@@ -482,6 +573,7 @@ swfdec_script_execute (SwfdecScript *scr
frame.script = NULL;
frame.varobj = obj;
frame.fun = NULL;
+ frame.swf = script;
frame.thisp = obj;
frame.argc = frame.nvars = 0;
frame.argv = frame.vars = NULL;
diff-tree 3e6fcd37cb3157514beaf45cb90e2c68d2138b86 (from bbafcb875054f54987db4b37da1bd6f40ada79f4)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 17 22:51:10 2007 +0100
remove leftover code from when the root movie contained the root script
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 30eb161..f5bf871 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -693,8 +693,7 @@ mc_framesloaded (JSContext *cx, JSObject
g_assert (movie);
/* only root movies can be partially loaded */
- if (SWFDEC_IS_ROOT_MOVIE (movie) ||
- SWFDEC_IS_ROOT_MOVIE (movie->parent)) {
+ if (SWFDEC_IS_ROOT_MOVIE (movie)) {
SwfdecDecoder *dec = SWFDEC_ROOT_MOVIE (movie->root)->decoder;
loaded = dec->frames_loaded;
g_assert (loaded <= movie->n_frames);
More information about the Swfdec
mailing list