Benjamin Otte
2007-Mar-28 15:10 UTC
[Swfdec] Branch 'as' - 3 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_script.c libswfdec/swfdec_script.h
libswfdec/Makefile.am | 2 libswfdec/swfdec_as_context.c | 124 +++++++++++++++++++++++++++++++++++++++--- libswfdec/swfdec_as_context.h | 6 +- libswfdec/swfdec_as_frame.c | 98 +++++++++++++++++++++++++++++++++ libswfdec/swfdec_as_frame.h | 64 +++++++++++++++++++++ libswfdec/swfdec_as_object.c | 30 +++++----- libswfdec/swfdec_as_object.h | 15 ++++- libswfdec/swfdec_as_types.c | 5 + libswfdec/swfdec_as_types.h | 8 +- libswfdec/swfdec_script.c | 40 ++++++++----- libswfdec/swfdec_script.h | 1 11 files changed, 348 insertions(+), 45 deletions(-) New commits: diff-tree d5b0299d9f6cc23d8b3980ba8e34b1f76ae1902d (from 6d6ccd9c1477dc96ee2171d7bfe3cfceda5020e6) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 29 00:10:13 2007 +0200 more hacking on the ActionScript stuff, hooking up frames Also, includes a rename from SWFDEC_AS_IS_FOO to SWFDEC_IS_AS_FOO diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 1670407..8bf4e50 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -17,6 +17,7 @@ js_cflags = -I$(srcdir)/js/ -I./js -DXP_ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES = \ swfdec_as_context.c \ + swfdec_as_frame.c \ swfdec_as_object.c \ swfdec_as_types.c \ swfdec_amf.c \ @@ -110,6 +111,7 @@ libswfdec_@SWFDEC_MAJORMINOR@include_HEA noinst_HEADERS = \ swfdec_as_context.h \ + swfdec_as_frame.h \ swfdec_as_object.h \ swfdec_as_types.h \ swfdec_amf.h \ diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 8b05dc3..e9bdc80 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -23,9 +23,11 @@ #include <string.h> #include "swfdec_as_context.h" +#include "swfdec_as_frame.h" #include "swfdec_as_object.h" #include "swfdec_as_types.h" #include "swfdec_debug.h" +#include "swfdec_script.h" /*** GTK_DOC ***/ @@ -67,7 +69,7 @@ swfdec_as_context_abort (SwfdecAsContext gboolean swfdec_as_context_use_mem (SwfdecAsContext *context, gsize len) { - g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), FALSE); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE); g_return_val_if_fail (len > 0, FALSE); context->memory += len; @@ -77,7 +79,7 @@ swfdec_as_context_use_mem (SwfdecAsConte void swfdec_as_context_unuse_mem (SwfdecAsContext *context, gsize len) { - g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context)); + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); g_return_if_fail (len > 0); g_return_if_fail (context->memory >= len); @@ -166,7 +168,7 @@ swfdec_as_string_mark (const char *strin void swfdec_as_value_mark (SwfdecAsValue *value) { - g_return_if_fail (SWFDEC_AS_IS_VALUE (value)); + g_return_if_fail (SWFDEC_IS_AS_VALUE (value)); if (SWFDEC_AS_VALUE_IS_OBJECT (value)) { swfdec_as_object_mark (SWFDEC_AS_VALUE_GET_OBJECT (value)); @@ -187,7 +189,7 @@ swfdec_as_context_mark_roots (gpointer k void swfdec_as_context_gc (SwfdecAsContext *context) { - g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context)); + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); SWFDEC_INFO ("invoking the garbage collector"); g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL); @@ -244,7 +246,7 @@ swfdec_as_context_create_string (SwfdecA char *new; if (!swfdec_as_context_use_mem (context, sizeof (char) * (2 + len))) - return SWFDEC_AS_EMPTY_STRING; + return SWFDEC_AS_STR_EMPTY; new = g_slice_alloc (2 + len); memcpy (&new[1], string, len); @@ -261,7 +263,7 @@ swfdec_as_context_get_string (SwfdecAsCo const char *ret; gsize len; - g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), NULL); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); g_return_val_if_fail (string != NULL, NULL); ret = g_hash_table_lookup (context->strings, string); @@ -277,3 +279,111 @@ swfdec_as_context_new (void) { return g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL); } + +/* defines minimum and maximum versions for which we have seperate scripts */ +#define MINSCRIPTVERSION 3 +#define MAXSCRIPTVERSION 7 +#define EXTRACT_VERSION(v) MIN ((v) - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION) + +typedef JSBool (* SwfdecActionExec) (JSContext *cx, guint action, const guint8 *data, guint len); +typedef struct { + const char * name; /* name identifying the action */ + char * (* print) (guint action, const guint8 *data, guint len); + int remove; /* values removed from stack or -1 for dynamic */ + int add; /* values added to the stack or -1 for dynamic */ + SwfdecActionExec exec[MAXSCRIPTVERSION - MINSCRIPTVERSION + 1]; + /* array is for version 3, 4, 5, 6, 7+ */ +} SwfdecActionSpec; + +extern const SwfdecActionSpec actions[256]; +void +swfdec_as_context_run (SwfdecAsContext *context) +{ + SwfdecAsFrame *frame; + SwfdecScript *script; + const SwfdecActionSpec *spec; + guint8 *startpc, *pc, *endpc, *nextpc; + guint action, len; + guint8 *data; + int version; + + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); + + /* setup data */ + frame = context->frame; + if (frame == NULL) + return; + script = frame->script; + version = EXTRACT_VERSION (script->version); + startpc = script->buffer->data; + endpc = startpc + script->buffer->length; + + while (pc != endpc) { + if (pc < startpc || pc >= endpc) { + SWFDEC_ERROR ("pc %p not in valid range [%p, %p) anymore", pc, startpc, endpc); + goto internal_error; + } + + /* decode next action */ + action = *pc; + spec = actions + action; + if (action == 0) + break; + if (action & 0x80) { + if (pc + 2 >= endpc) { + SWFDEC_ERROR ("action %u length value out of range", action); + goto internal_error; + } + data = pc + 3; + len = pc[1] | pc[2] << 8; + if (data + len > endpc) { + SWFDEC_ERROR ("action %u length %u out of range", action, len); + goto internal_error; + } + nextpc = pc + 3 + len; + } else { + data = NULL; + len = 0; + nextpc = pc + 1; + } + /* check action is valid */ + if (spec->exec[version] == NULL) { + SWFDEC_ERROR ("cannot interpret action %u %s for version %u", action, + spec->name ? spec->name : "Unknown", script->version); + goto internal_error; + } +#if 0 + if (spec->remove > 0) { + //!swfdec_script_ensure_stack (cx, spec->remove)) { + } + if (spec->add > 0 && + TRUE) { //fp->sp + spec->add - MAX (spec->remove, 0) > fp->spend) { + SWFDEC_ERROR ("FIXME: implement stack expansion, we got an overflow"); + goto internal_error; + } +#ifndef G_DISABLE_ASSERT + checksp = (spec->add >= 0 && spec->remove >= 0) ? fp->sp + spec->add - spec->remove : NULL; +#endif +#endif + spec->exec[version] (NULL, action, data, len); +#if 0 +#ifndef G_DISABLE_ASSERT + if (checksp != NULL && checksp != fp->sp) { + /* check stack was handled like expected */ + g_error ("action %s was supposed to change the stack by %d (+%d -%d), but it changed by %td", + spec->name, spec->add - spec->remove, spec->add, spec->remove, + fp->sp - checksp + spec->add - spec->remove); + } +#endif + if (fp->pc == pc) { + fp->pc = pc = nextpc; + } else { + pc = fp->pc; + } +#endif + } + +internal_error: + return; +} + diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h index 05ac561..67e7ec2 100644 --- a/libswfdec/swfdec_as_context.h +++ b/libswfdec/swfdec_as_context.h @@ -37,8 +37,8 @@ typedef enum { typedef struct _SwfdecAsContextClass SwfdecAsContextClass; #define SWFDEC_TYPE_AS_CONTEXT (swfdec_as_context_get_type()) -#define SWFDEC_AS_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_CONTEXT)) -#define SWFDEC_AS_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_CONTEXT)) +#define SWFDEC_IS_AS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_CONTEXT)) +#define SWFDEC_IS_AS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_CONTEXT)) #define SWFDEC_AS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContext)) #define SWFDEC_AS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContextClass)) #define SWFDEC_AS_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContextClass)) @@ -55,6 +55,7 @@ struct _SwfdecAsContext { /* execution state */ unsigned int version; /* currently active version */ + SwfdecAsFrame * frame; /* topmost stack frame */ }; struct _SwfdecAsContextClass { diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c new file mode 100644 index 0000000..8ce86db --- /dev/null +++ b/libswfdec/swfdec_as_frame.c @@ -0,0 +1,98 @@ +/* SwfdecAs + * Copyright (C) 2007 Benjamin Otte <otte@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 "swfdec_as_frame.h" +#include "swfdec_as_context.h" +#include "swfdec_debug.h" + +G_DEFINE_TYPE (SwfdecAsFrame, swfdec_as_frame, SWFDEC_TYPE_AS_OBJECT) + +static void +swfdec_as_frame_dispose (GObject *object) +{ + SwfdecAsFrame *frame = SWFDEC_AS_FRAME (object); + + g_slice_free1 (sizeof (SwfdecAsValue) * frame->n_registers, frame->registers); + swfdec_script_unref (frame->script); + + G_OBJECT_CLASS (swfdec_as_frame_parent_class)->dispose (object); +} + +static void +swfdec_as_frame_mark (SwfdecAsObject *object) +{ + SwfdecAsFrame *frame = SWFDEC_AS_FRAME (object); + guint i; + + swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->next)); + swfdec_as_object_mark (frame->scope); + swfdec_as_object_mark (frame->var_object); + for (i = 0; i < frame->n_registers; i++) { + swfdec_as_value_mark (&frame->registers[i]); + } + SWFDEC_AS_OBJECT_CLASS (swfdec_as_frame_parent_class)->mark (object); +} + +static void +swfdec_as_frame_class_init (SwfdecAsFrameClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); + + object_class->dispose = swfdec_as_frame_dispose; + + asobject_class->mark = swfdec_as_frame_mark; +} + +static void +swfdec_as_frame_init (SwfdecAsFrame *frame) +{ +} + +SwfdecAsFrame * +swfdec_as_frame_new (SwfdecAsContext *context, SwfdecAsObject *thisp, SwfdecScript *script) +{ + SwfdecAsValue val; + SwfdecAsFrame *frame; + gsize size; + + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (thisp), NULL); + g_return_val_if_fail (script != NULL, NULL); + + size = sizeof (SwfdecAsObject) + sizeof (SwfdecAsValue) * script->n_registers; + if (!swfdec_as_context_use_mem (context, size)) + return NULL; + frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL); + swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size); + g_object_unref (frame); + frame->next = context->frame; + context->frame = frame; + frame->scope = thisp; + frame->var_object = thisp; + frame->registers = g_slice_alloc0 (sizeof (SwfdecAsValue) * script->n_registers); + SWFDEC_AS_VALUE_SET_OBJECT (&val, thisp); + swfdec_as_object_set (SWFDEC_AS_OBJECT (frame), SWFDEC_AS_STR_THIS, &val); + return frame; +} + diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h new file mode 100644 index 0000000..f55cc8f --- /dev/null +++ b/libswfdec/swfdec_as_frame.h @@ -0,0 +1,64 @@ +/* SwfdecAs + * Copyright (C) 2007 Benjamin Otte <otte@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_FRAME_H_ +#define _SWFDEC_AS_FRAME_H_ + +#include <libswfdec/swfdec_as_object.h> +#include <libswfdec/swfdec_as_types.h> +#include <libswfdec/swfdec_script.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecAsFrameClass SwfdecAsFrameClass; + +#define SWFDEC_TYPE_AS_FRAME (swfdec_as_frame_get_type()) +#define SWFDEC_IS_AS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_FRAME)) +#define SWFDEC_IS_AS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_FRAME)) +#define SWFDEC_AS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrame)) +#define SWFDEC_AS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrameClass)) +#define SWFDEC_AS_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrameClass)) + +struct _SwfdecAsFrame { + SwfdecAsObject object; + + SwfdecAsFrame * next; /* next frame (FIXME: keep a list in the context instead?) */ + SwfdecScript * script; /* script being executed */ + SwfdecAsObject * scope; /* scope object coming after this */ + SwfdecAsObject * var_object; /* new variables go here */ + SwfdecAsValue * registers; /* the registers */ + guint n_registers; /* number of allocated registers */ + SwfdecConstantPool * constant_pool; /* constant pool currently in use */ + //SwfdecAsStack * stack; /* variables on the stack */ +}; + +struct _SwfdecAsFrameClass { + SwfdecAsObjectClass object_class; +}; + +GType swfdec_as_frame_get_type (void); + +SwfdecAsFrame * swfdec_as_frame_new (SwfdecAsContext * context, + SwfdecAsObject * thisp, + SwfdecScript * script); + + + +G_END_DECLS +#endif diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index c1a3bd8..79ce1cf 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -79,8 +79,10 @@ swfdec_as_object_new (SwfdecAsContext *c { SwfdecAsObject *object; - g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), NULL); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsObject))) + return NULL; object = g_object_new (SWFDEC_TYPE_AS_OBJECT, NULL); swfdec_as_object_add (object, context, sizeof (SwfdecAsObject)); g_object_unref (object); @@ -90,12 +92,10 @@ swfdec_as_object_new (SwfdecAsContext *c void swfdec_as_object_add (SwfdecAsObject *object, SwfdecAsContext *context, gsize size) { - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); - g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); g_return_if_fail (object->properties == NULL); - if (!swfdec_as_context_use_mem (context, size)) - return; object->context = context; object->size = size; g_hash_table_insert (context->objects, object, object); @@ -115,7 +115,7 @@ swfdec_as_object_free_property (gpointer void swfdec_as_object_collect (SwfdecAsObject *object) { - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (object->properties != NULL); g_hash_table_foreach (object->properties, swfdec_as_object_free_property, object); @@ -128,7 +128,7 @@ swfdec_as_object_collect (SwfdecAsObject void swfdec_as_object_root (SwfdecAsObject *object) { - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) == 0); object->flags |= SWFDEC_AS_GC_ROOT; @@ -137,7 +137,7 @@ swfdec_as_object_root (SwfdecAsObject *o void swfdec_as_object_unroot (SwfdecAsObject *object) { - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) != 0); object->flags &= ~SWFDEC_AS_GC_ROOT; @@ -150,9 +150,9 @@ swfdec_as_object_set_variable (SwfdecAsO const char *s; SwfdecAsObjectVariable *var; - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); - g_return_if_fail (SWFDEC_AS_IS_VALUE (variable)); - g_return_if_fail (SWFDEC_AS_IS_VALUE (value)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_VALUE (variable)); + g_return_if_fail (SWFDEC_IS_AS_VALUE (value)); s = swfdec_as_value_to_string (object->context, variable); var = g_hash_table_lookup (object->properties, s); @@ -177,8 +177,8 @@ swfdec_as_object_get_variable (SwfdecAsO SwfdecAsObjectVariable *var; guint i; - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); - g_return_if_fail (SWFDEC_AS_IS_VALUE (variable)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_VALUE (variable)); g_return_if_fail (value != NULL); s = swfdec_as_value_to_string (object->context, variable); @@ -206,8 +206,8 @@ swfdec_as_object_delete_variable (Swfdec SwfdecAsObjectVariable *var; guint i; - g_return_if_fail (SWFDEC_AS_IS_OBJECT (object)); - g_return_if_fail (SWFDEC_AS_IS_VALUE (variable)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (SWFDEC_IS_AS_VALUE (variable)); s = swfdec_as_value_to_string (object->context, variable); for (i = 0; i < 256 && object != NULL; i++) { diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h index 581d0f2..0accee4 100644 --- a/libswfdec/swfdec_as_object.h +++ b/libswfdec/swfdec_as_object.h @@ -34,8 +34,8 @@ typedef enum { typedef struct _SwfdecAsObjectClass SwfdecAsObjectClass; #define SWFDEC_TYPE_AS_OBJECT (swfdec_as_object_get_type()) -#define SWFDEC_AS_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_OBJECT)) -#define SWFDEC_AS_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_OBJECT)) +#define SWFDEC_IS_AS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_OBJECT)) +#define SWFDEC_IS_AS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_OBJECT)) #define SWFDEC_AS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObject)) #define SWFDEC_AS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass)) #define SWFDEC_AS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass)) @@ -77,6 +77,17 @@ void swfdec_as_object_get_variable (Swf SwfdecAsValue * value); void swfdec_as_object_delete_variable(SwfdecAsObject * object, const SwfdecAsValue * variable); +/* shortcuts, you probably don't want to bind them */ +#define swfdec_as_object_set(object, name, value) G_STMT_START { \ + SwfdecAsValue __variable; \ + SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \ + swfdec_as_object_set_variable ((object), &__variable, (value)); \ +}G_STMT_END +#define swfdec_as_object_get(object, name, value) G_STMT_START { \ + SwfdecAsValue __variable; \ + SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \ + swfdec_as_object_get_variable ((object), &__variable, (value)); \ +}G_STMT_END G_END_DECLS diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c index bc932e9..2b84330 100644 --- a/libswfdec/swfdec_as_types.c +++ b/libswfdec/swfdec_as_types.c @@ -30,6 +30,7 @@ const char *swfdec_as_strings[] = { SWFDEC_AS_CONSTANT_STRING (""), SWFDEC_AS_CONSTANT_STRING ("__proto__"), + SWFDEC_AS_CONSTANT_STRING ("this"), /* add more here */ NULL }; @@ -37,8 +38,8 @@ const char *swfdec_as_strings[] = { const char * swfdec_as_value_to_string (SwfdecAsContext *context, const SwfdecAsValue *value) { - g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), SWFDEC_AS_EMPTY_STRING); - g_return_val_if_fail (SWFDEC_AS_IS_VALUE (value), SWFDEC_AS_EMPTY_STRING); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_AS_STR_EMPTY); + g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), SWFDEC_AS_STR_EMPTY); if (SWFDEC_AS_VALUE_IS_STRING (value)) { return SWFDEC_AS_VALUE_GET_STRING (value); diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h index f171341..6fe9fbc 100644 --- a/libswfdec/swfdec_as_types.h +++ b/libswfdec/swfdec_as_types.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS typedef guint8 SwfdecAsType; typedef struct _SwfdecAsContext SwfdecAsContext; +typedef struct _SwfdecAsFrame SwfdecAsFrame; typedef struct _SwfdecAsObject SwfdecAsObject; typedef struct _SwfdecAsValue SwfdecAsValue; @@ -48,7 +49,7 @@ struct _SwfdecAsValue { } value; }; -#define SWFDEC_AS_IS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT) +#define SWFDEC_IS_AS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT) #define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_TYPE_AS_UNDEFINED) #define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_TYPE_AS_UNDEFINED @@ -87,8 +88,9 @@ struct _SwfdecAsValue { /* List of static strings that are required all the time */ extern const char *swfdec_as_strings[]; -#define SWFDEC_AS_EMPTY_STRING (swfdec_as_strings[0] + 1) -#define SWFDEC_AS_PROTO_STRING (swfdec_as_strings[1] + 1) +#define SWFDEC_AS_STR_EMPTY (swfdec_as_strings[0] + 1) +#define SWFDEC_AS_STR_PROTO (swfdec_as_strings[1] + 1) +#define SWFDEC_AS_STR_THIS (swfdec_as_strings[2] + 1) const char * swfdec_as_value_to_string (SwfdecAsContext * context, diff-tree 6d6ccd9c1477dc96ee2171d7bfe3cfceda5020e6 (from 97c15c36effab2617b4f5157374f7612b7e8379e) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 29 00:08:33 2007 +0200 let scripts handle their number of registers Also, implement swfdec_constant_pool_attach_to_context, which puts all strings of a context into a context diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index a9f16e0..6b7477e 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -22,6 +22,7 @@ #endif #include "swfdec_script.h" +#include "swfdec_as_context.h" #include "swfdec_debug.h" #include "swfdec_debugger.h" #include "swfdec_scriptable.h" @@ -82,6 +83,20 @@ swfdec_constant_pool_new_from_action (co return pool; } +void +swfdec_constant_pool_attach_to_context (SwfdecConstantPool *pool, SwfdecAsContext *context) +{ + guint i; + + g_return_if_fail (pool != NULL); + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); + + for (i = 0; i < pool->len; i++) { + g_ptr_array_index (pool, i) = (gpointer) swfdec_as_context_get_string (context, + g_ptr_array_index (pool, i)); + } +} + guint swfdec_constant_pool_size (SwfdecConstantPool *pool) { @@ -174,14 +189,8 @@ swfdec_script_ensure_stack (JSContext *c return JS_TRUE; } -static gboolean -swfdec_action_has_register (JSContext *cx, guint i) -{ - if (cx->fp->fun == NULL) - return i < 4; - else - return i < cx->fp->fun->nvars; -} +#define swfdec_action_has_register(cx, i) \ + ((i) < ((SwfdecScript *) (cx)->fp->swf)->n_registers) static SwfdecMovie * swfdec_action_get_target (JSContext *cx) @@ -1707,20 +1716,21 @@ swfdec_action_define_function (JSContext if (fun == NULL) return JS_FALSE; if (v2) { - fun->nvars = swfdec_bits_get_u8 (&bits) + 1; + script->n_registers = swfdec_bits_get_u8 (&bits) + 1; flags = swfdec_bits_get_u16 (&bits); preloads = g_new0 (guint8, n_args); } else { - fun->nvars = 5; + script->n_registers = 5; } + fun->nvars = script->n_registers; for (i = 0; i < n_args; i++) { JSAtom *atom; const char *arg_name; if (v2) { guint preload = swfdec_bits_get_u8 (&bits); - if (preload && preload >= fun->nvars) { + if (preload && preload >= script->n_registers) { SWFDEC_ERROR ("argument %u is preloaded into register %u out of %u", - i, preload, fun->nvars); + i, preload, script->n_registers); return JS_FALSE; } if (preload != 0) { @@ -2489,7 +2499,7 @@ typedef struct { /* array is for version 3, 4, 5, 6, 7+ */ } SwfdecActionSpec; -static const SwfdecActionSpec actions[256] = { +const SwfdecActionSpec actions[256] = { /* version 3 */ [0x04] = { "NextFrame", NULL, 0, 0, { swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame } }, [0x05] = { "PreviousFrame", NULL, 0, 0, { swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame } }, @@ -2731,6 +2741,8 @@ swfdec_script_new (SwfdecBits *bits, con script->refcount = 1; script->name = g_strdup (name ? name : "Unnamed script"); script->version = version; + /* by default, a function has 4 registers */ + script->n_registers = 5; /* These flags are the default arguments used by scripts read from a file. * DefineFunction and friends override this */ script->flags = SWFDEC_SCRIPT_SUPPRESS_ARGS; @@ -3102,7 +3114,7 @@ swfdec_script_execute (SwfdecScript *scr frame.scopeChain = obj; frame.varobj = obj; /* allocate stack for variables */ - frame.nvars = 4; + frame.nvars = script->n_registers; frame.vars = js_AllocRawStack (cx, frame.nvars, &mark); if (frame.vars == NULL) { return JS_FALSE; diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h index d55cdbc..b8fdcbb 100644 --- a/libswfdec/swfdec_script.h +++ b/libswfdec/swfdec_script.h @@ -53,6 +53,7 @@ struct _SwfdecScript { unsigned int refcount; /* reference count */ char * name; /* name identifying this script */ unsigned int version; /* version of the script */ + unsigned int n_registers; /* number of registers */ gpointer debugger; /* debugger owning us or NULL */ /* needed by functions */ SwfdecBuffer * constant_pool; /* constant pool action */ diff-tree 97c15c36effab2617b4f5157374f7612b7e8379e (from d906de1000e1ad4859df4b84c6b67129e70b3ac2) Author: Benjamin Otte <otte@gnome.org> Date: Wed Mar 28 16:45:19 2007 +0200 export swfdec_object_mark diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 84f617f..8b05dc3 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -142,7 +142,7 @@ swfdec_as_context_collect (SwfdecAsConte g_print (">> done collecting garbage\n"); } -static inline void +void swfdec_as_object_mark (SwfdecAsObject *object) { SwfdecAsObjectClass *klass; diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h index 3dde6c1..05ac561 100644 --- a/libswfdec/swfdec_as_context.h +++ b/libswfdec/swfdec_as_context.h @@ -76,6 +76,7 @@ gboolean swfdec_as_context_use_mem gsize len); void swfdec_as_context_unuse_mem (SwfdecAsContext * context, gsize len); +void swfdec_as_object_mark (SwfdecAsObject * object); void swfdec_as_value_mark (SwfdecAsValue * value); void swfdec_as_string_mark (const char * string); void swfdec_as_context_gc (SwfdecAsContext * context);
Possibly Parallel Threads
- Branch 'as' - 9 commits - configure.ac doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_stack.c
- Branch 'as' - 14 commits - libswfdec-gtk/swfdec_playback_alsa.c 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
- 5 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_scope.c libswfdec/swfdec_as_scope.h libswfdec/swfdec_as_script_function.c
- Branch 'as' - 24 commits - configure.ac doc/Makefile.am doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_as_array.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c
- 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