Benjamin Otte
2007-Sep-13 17:36 UTC
[Swfdec] 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 libswfdec/swfdec_as_script_function.h libswfdec/swfdec_as_with.c libswfdec/swfdec_as_with.h
libswfdec/Makefile.am | 4 libswfdec/swfdec_as_context.c | 39 ++---- libswfdec/swfdec_as_frame.c | 218 ++++++++++++++++++++-------------- libswfdec/swfdec_as_frame_internal.h | 38 ++++- libswfdec/swfdec_as_interpret.c | 39 +++--- libswfdec/swfdec_as_scope.c | 78 ------------ libswfdec/swfdec_as_scope.h | 55 -------- libswfdec/swfdec_as_script_function.c | 10 - libswfdec/swfdec_as_script_function.h | 6 libswfdec/swfdec_as_with.c | 143 ---------------------- libswfdec/swfdec_as_with.h | 56 -------- 11 files changed, 207 insertions(+), 479 deletions(-) New commits: diff-tree ef4b8c89c3e50cdd36402301e9aad38270accf24 (from 7abe5c03e87fbfd281426b1cf06e2d4890698338) Author: Benjamin Otte <otte at gnome.org> Date: Thu Sep 13 19:34:54 2007 +0200 replace swfdec_as_frame_find_variable with _get/set_variable Since the setting code works way differet from the getting code, it seemed clever to make them 2 different functions diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 035e1fd..733192d 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -963,16 +963,11 @@ swfdec_as_context_eval_get_property (Swf swfdec_as_object_get_variable (obj, name, ret); } else { if (cx->frame) { - obj = swfdec_as_frame_find_variable (cx->frame, name); - if (obj) { - swfdec_as_object_get_variable (obj, name, ret); - return; - } + swfdec_as_frame_get_variable (cx->frame, name, ret); } else { SWFDEC_WARNING ("eval called without a frame"); swfdec_as_object_get_variable (cx->global, name, ret); } - SWFDEC_AS_VALUE_SET_UNDEFINED (ret); } } @@ -985,11 +980,10 @@ swfdec_as_context_eval_set_property (Swf SWFDEC_ERROR ("no frame in eval_set?"); return; } - obj = swfdec_as_frame_find_variable (cx->frame, name); - if (obj == NULL || obj == cx->global) - obj = cx->frame->target; + swfdec_as_frame_set_variable (cx->frame, name, ret); + } else { + swfdec_as_object_set_variable (obj, name, ret); } - swfdec_as_object_set_variable (obj, name, ret); } static void diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c index 5620ac7..c11c03a 100644 --- a/libswfdec/swfdec_as_frame.c +++ b/libswfdec/swfdec_as_frame.c @@ -535,45 +535,72 @@ swfdec_as_frame_set_this (SwfdecAsFrame } /** - * swfdec_as_frame_find_variable: + * swfdec_as_frame_get_variable_and_flags: * @frame: a #SwfdecAsFrame - * @variable: name of the variable to find + * @variable: name of the variable + * @value: pointer to take value of the variable or %NULL + * @flags: pointer to take flags or %NULL + * @pobject: pointer to take the actual object that held the variable or %NULL + * + * Walks the scope chain of @frame trying to resolve the given @variable and if + * found, returns its value and flags. Note that there might be a difference + * between @pobject and the returned object, since the returned object will be + * part of the scope chain while @pobject will contain the actual property. It + * will be a prototype of the returned object though. * - * Finds the given variable in the current scope chain. Returns the first - * object in the scope chain that contains this variable in its prototype - * chain. If you want to know the explicit object that contains the variable, - * you have to call swfdec_as_object_get_variable_and_flags() on the result. - * If no such variable exist in the scope chain, %NULL is returned. - * <note>The returned object might be an internal object. You probably do not - * want to expose it to scripts. Call swfdec_as_object_resolve () on the - * returned value to be sure of not having an internal object.</note> - * - * Returns: the object that contains @variable or %NULL if none. + * Returns: Object in scope chain that contained the variable. **/ SwfdecAsObject * -swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const char *variable) +swfdec_as_frame_get_variable_and_flags (SwfdecAsFrame *frame, const char *variable, + SwfdecAsValue *value, guint *flags, SwfdecAsObject **pobject) { GSList *walk; - SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); g_return_val_if_fail (variable != NULL, NULL); for (walk = frame->scope_chain; walk; walk = walk->next) { - if (swfdec_as_object_get_variable (walk->data, variable, &val)) - return SWFDEC_AS_OBJECT (walk->data); + if (swfdec_as_object_get_variable_and_flags (walk->data, variable, value, + flags, pobject)) + return walk->data; } /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target */ - if (swfdec_as_object_get_variable (frame->target, variable, &val)) + if (swfdec_as_object_get_variable_and_flags (frame->target, variable, value, + flags, pobject)) return frame->target; /* 2) the global object */ - if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable, &val)) + if (swfdec_as_object_get_variable_and_flags ( + SWFDEC_AS_OBJECT (frame)->context->global, variable, value, flags, pobject)) return SWFDEC_AS_OBJECT (frame)->context->global; return NULL; } +void +swfdec_as_frame_set_variable_and_flags (SwfdecAsFrame *frame, const char *variable, + const SwfdecAsValue *value, guint default_flags) +{ + SwfdecAsObject *pobject, *set; + GSList *walk; + + g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); + g_return_if_fail (variable != NULL); + + set = NULL; + for (walk = frame->scope_chain; walk; walk = walk->next) { + if (swfdec_as_object_get_variable_and_flags (walk->data, variable, NULL, NULL, &pobject) && + pobject == walk->data) { + set = walk->data; + break; + } + } + if (set == NULL) + set = frame->target; + + swfdec_as_object_set_variable_and_flags (set, variable, value, default_flags); +} + SwfdecAsDeleteReturn swfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable) { @@ -721,25 +748,14 @@ swfdec_as_frame_preload (SwfdecAsFrame * } } if (script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT && current_reg < script->n_registers) { - SwfdecAsObject *obj; - - obj = swfdec_as_frame_find_variable (frame, SWFDEC_AS_STR__root); - if (obj) { - swfdec_as_object_get_variable (obj, SWFDEC_AS_STR__root, &frame->registers[current_reg]); - } else { + if (!swfdec_as_frame_get_variable (frame, SWFDEC_AS_STR__root, &frame->registers[current_reg])) { SWFDEC_WARNING ("no root to preload"); - SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); } + current_reg++; } if (script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT && current_reg < script->n_registers) { - SwfdecAsObject *obj; - - obj = swfdec_as_frame_find_variable (frame, SWFDEC_AS_STR__parent); - if (obj) { - swfdec_as_object_get_variable (obj, SWFDEC_AS_STR__parent, &frame->registers[current_reg++]); - } else { - SWFDEC_WARNING ("no parent to preload"); - SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); + if (!swfdec_as_frame_get_variable (frame, SWFDEC_AS_STR__parent, &frame->registers[current_reg])) { + SWFDEC_WARNING ("no root to preload"); } current_reg++; } diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h index 280f48a..be9d1ae 100644 --- a/libswfdec/swfdec_as_frame_internal.h +++ b/libswfdec/swfdec_as_frame_internal.h @@ -72,8 +72,21 @@ void swfdec_as_frame_set_this (SwfdecAs SwfdecAsObject * thisp); void swfdec_as_frame_preload (SwfdecAsFrame * frame); -SwfdecAsObject *swfdec_as_frame_find_variable (SwfdecAsFrame * frame, - const char * variable); +#define swfdec_as_frame_get_variable(frame, variable, value) \ + swfdec_as_frame_get_variable_and_flags (frame, variable, value, NULL, NULL) +SwfdecAsObject *swfdec_as_frame_get_variable_and_flags + (SwfdecAsFrame * frame, + const char * variable, + SwfdecAsValue * value, + guint * flags, + SwfdecAsObject ** pobject); +#define swfdec_as_frame_set_variable(frame, variable, value) \ + swfdec_as_frame_set_variable_and_flags (frame, variable, value, 0) +void swfdec_as_frame_set_variable_and_flags + (SwfdecAsFrame * frame, + const char * variable, + const SwfdecAsValue * value, + guint default_flags); SwfdecAsDeleteReturn swfdec_as_frame_delete_variable (SwfdecAsFrame * frame, const char * variable); diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 70f3c09..b9204a6 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -578,16 +578,14 @@ swfdec_action_get_variable (SwfdecAsCont val = swfdec_as_stack_peek (cx, 1); s = swfdec_as_value_to_string (cx, val); if (swfdec_action_get_movie_by_path (cx, s, &object, &s)) { - if (object == NULL) - object = swfdec_as_frame_find_variable (cx->frame, s); - } else { - object = NULL; - } - if (object != NULL) { - if (s) { - swfdec_as_object_get_variable (object, swfdec_as_context_get_string (cx, s), val); + if (object) { + if (s) { + swfdec_as_object_get_variable (object, swfdec_as_context_get_string (cx, s), val); + } else { + SWFDEC_AS_VALUE_SET_OBJECT (val, object); + } } else { - SWFDEC_AS_VALUE_SET_OBJECT (val, object); + swfdec_as_frame_get_variable (cx->frame, swfdec_as_context_get_string (cx, s), val); } } else { SWFDEC_AS_VALUE_SET_UNDEFINED (val); @@ -791,9 +789,8 @@ swfdec_action_call_function (SwfdecAsCon name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)); thisp = swfdec_as_stack_peek (cx, 2); fun = swfdec_as_stack_peek (cx, 1); - obj = swfdec_as_frame_find_variable (frame, name); + obj = swfdec_as_frame_get_variable (frame, name, fun); if (obj) { - swfdec_as_object_get_variable (obj, name, fun); SWFDEC_AS_VALUE_SET_OBJECT (thisp, obj); } else { SWFDEC_AS_VALUE_SET_NULL (thisp); diff-tree 7abe5c03e87fbfd281426b1cf06e2d4890698338 (from c4ba717de9a7bcabb49dcf5efd94c0dfd4a1fea5) Author: Benjamin Otte <otte at gnome.org> Date: Thu Sep 13 15:49:54 2007 +0200 properly exit when pc == endpc diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index e332c5b..035e1fd 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -797,6 +797,10 @@ start: goto start; } if (pc < startpc || pc >= endpc) { + if (pc == endpc) { + swfdec_as_frame_return (frame, NULL); + goto start; + } SWFDEC_ERROR ("pc %p not in valid range [%p, %p) anymore", pc, startpc, endpc); goto error; } diff-tree c4ba717de9a7bcabb49dcf5efd94c0dfd4a1fea5 (from parents) Merge: f5f3a3978cf4b5ce623f2d0118f5936c9d1608a6 8fcb6912a4fb328bc33fea63ccb4816a7fc47e4d Author: Benjamin Otte <otte at gnome.org> Date: Thu Sep 13 14:28:41 2007 +0200 Merge branch 'master' of ssh://company at git.freedesktop.org/git/swfdec/swfdec diff-tree f5f3a3978cf4b5ce623f2d0118f5936c9d1608a6 (from parents) Merge: 8c921f54f26b483cd271a0677bb6e731bf7feb0b 7028d035feb026c8f194d4d27be9348ff294fc10 Author: Benjamin Otte <otte at gnome.org> Date: Thu Sep 13 13:38:00 2007 +0200 Merge branch 'master' of ssh://company at git.freedesktop.org/git/swfdec/swfdec diff-tree 8c921f54f26b483cd271a0677bb6e731bf7feb0b (from 93f0e1b0eaeb04357370f7daf9ea8dbbe3786d3e) Author: Benjamin Otte <otte at gnome.org> Date: Thu Sep 13 13:36:03 2007 +0200 rewrite scope chain handling Previously we had lots of scope objects that were instantiated whenever the scope chain changed. Now it's just a list of objects in the scope chain. It also adds a function swfdec_as_frame_push_block() that allows registering a callback that gets called whenever the program counter leaves that block. It is used for implementing With and should also work for try/catch. diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index b3e5bdf..ca6d565 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -32,14 +32,12 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES swfdec_as_native_function.c \ swfdec_as_number.c \ swfdec_as_object.c \ - swfdec_as_scope.c \ swfdec_as_script_function.c \ swfdec_as_stack.c \ swfdec_as_string.c \ swfdec_as_strings.c \ swfdec_as_super.c \ swfdec_as_types.c \ - swfdec_as_with.c \ swfdec_amf.c \ swfdec_asbroadcaster.c \ swfdec_audio.c \ @@ -162,13 +160,11 @@ noinst_HEADERS = \ swfdec_as_date.h \ swfdec_as_interpret.h \ swfdec_as_number.h \ - swfdec_as_scope.h \ swfdec_as_script_function.h \ swfdec_as_stack.h \ swfdec_as_string.h \ swfdec_as_strings.h \ swfdec_as_super.h \ - swfdec_as_with.h \ swfdec_asnative.h \ swfdec_amf.h \ swfdec_audio_internal.h \ diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 89859d3..e332c5b 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -711,7 +711,7 @@ swfdec_as_context_run (SwfdecAsContext * int version; guint original_version; void (* step) (SwfdecAsDebugger *debugger, SwfdecAsContext *context); - gboolean check_scope; /* some opcodes avoid a scope check */ + gboolean check_block; /* some opcodes avoid a scope check */ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); if (context->frame == NULL || context->state == SWFDEC_AS_CONTEXT_ABORTED) @@ -786,19 +786,20 @@ start: startpc = script->buffer->data; endpc = startpc + script->buffer->length; pc = frame->pc; - check_scope = TRUE; + check_block = TRUE; while (context->state < SWFDEC_AS_CONTEXT_ABORTED) { - if (pc == endpc) { - swfdec_as_frame_return (frame, NULL); - goto start; + if (check_block && (pc < frame->block_start || pc >= frame->block_end)) { + SWFDEC_LOG ("code exited block"); + swfdec_as_frame_check_block (frame); + pc = frame->pc; + if (frame != context->frame) + goto start; } if (pc < startpc || pc >= endpc) { SWFDEC_ERROR ("pc %p not in valid range [%p, %p) anymore", pc, startpc, endpc); goto error; } - if (check_scope) - swfdec_as_frame_check_scope (frame); /* decode next action */ action = *pc; @@ -847,7 +848,7 @@ start: SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, skipping it", action, action, spec->name ? spec->name : "Unknown", script->version); frame->pc = pc = nextpc; - check_scope = TRUE; + check_block = TRUE; continue; } SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, using version %u instead", @@ -875,10 +876,10 @@ start: /* FIXME: do this via flag? */ if (frame->pc == pc) { frame->pc = pc = nextpc; - check_scope = TRUE; + check_block = TRUE; } else { pc = frame->pc; - check_scope = FALSE; + check_block = FALSE; } if (frame == context->frame) { #ifndef G_DISABLE_ASSERT diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c index 52745bd..5620ac7 100644 --- a/libswfdec/swfdec_as_frame.c +++ b/libswfdec/swfdec_as_frame.c @@ -195,8 +195,71 @@ swfdec_as_stack_iterator_next (SwfdecAsS return iter->current; } +/*** BLOCK HANDLING ***/ -G_DEFINE_TYPE (SwfdecAsFrame, swfdec_as_frame, SWFDEC_TYPE_AS_SCOPE) +typedef struct { + const guint8 * start; /* start of block */ + const guint8 * end; /* end of block (hitting this address will exit the block) */ + SwfdecAsFrameBlockFunc func; /* function to call when block is exited */ + gpointer data; /* data to pass to function */ + GDestroyNotify destroy;/* destroy function called for data */ +} SwfdecAsFrameBlock; + +void +swfdec_as_frame_push_block (SwfdecAsFrame *frame, const guint8 *start, + const guint8 *end, SwfdecAsFrameBlockFunc func, gpointer data, GDestroyNotify destroy) +{ + SwfdecAsFrameBlock block = { start, end, func, data, destroy }; + + g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); + g_return_if_fail (start < end); + g_return_if_fail (start >= frame->block_start); + g_return_if_fail (end <= frame->block_end); + g_return_if_fail (func != NULL); + + frame->block_start = start; + frame->block_end = end; + g_array_append_val (frame->blocks, block); +} + +void +swfdec_as_frame_pop_block (SwfdecAsFrame *frame) +{ + SwfdecAsFrameBlock *block; + + g_assert (frame->blocks->len > 0); + + block = &g_array_index (frame->blocks, SwfdecAsFrameBlock, frame->blocks->len - 1); + if (block->destroy) { + block->destroy (block->data); + } + g_array_set_size (frame->blocks, frame->blocks->len - 1); + if (frame->blocks->len) { + block--; + frame->block_start = block->start; + frame->block_end = block->end; + } else { + /* FIXME: do we need to set the block_start and block_end here? */ + frame->block_start = NULL; + frame->block_end = NULL; + } +} + +void +swfdec_as_frame_check_block (SwfdecAsFrame *frame) +{ + SwfdecAsFrameBlock *block; + + g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); + g_assert (frame->blocks->len > 0); + + block = &g_array_index (frame->blocks, SwfdecAsFrameBlock, frame->blocks->len - 1); + block->func (frame, block->data); +} + +/*** FRAME ***/ + +G_DEFINE_TYPE (SwfdecAsFrame, swfdec_as_frame, SWFDEC_TYPE_AS_OBJECT) static void swfdec_as_frame_dispose (GObject *object) @@ -216,6 +279,9 @@ swfdec_as_frame_dispose (GObject *object swfdec_buffer_unref (frame->constant_pool_buffer); frame->constant_pool_buffer = NULL; } + while (frame->blocks->len > 0) + swfdec_as_frame_pop_block (frame); + g_array_free (frame->blocks, TRUE); G_OBJECT_CLASS (swfdec_as_frame_parent_class)->dispose (object); } @@ -228,8 +294,7 @@ swfdec_as_frame_mark (SwfdecAsObject *ob if (frame->next) swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->next)); - if (frame->scope) - swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->scope)); + g_slist_foreach (frame->scope_chain, (GFunc) swfdec_as_object_mark, NULL); if (frame->thisp) swfdec_as_object_mark (frame->thisp); if (frame->super) @@ -297,6 +362,8 @@ static void swfdec_as_frame_init (SwfdecAsFrame *frame) { frame->function_name = "unnamed"; + frame->blocks = g_array_new (FALSE, FALSE, sizeof (SwfdecAsFrameBlock)); + frame->block_end = (gpointer) -1; } static void @@ -329,7 +396,7 @@ swfdec_as_frame_new (SwfdecAsContext *co frame->function_name = script->name; SWFDEC_DEBUG ("new frame for function %s", frame->function_name); frame->pc = script->buffer->data; - frame->scope = SWFDEC_AS_SCOPE (frame); + frame->scope_chain = g_slist_prepend (frame->scope_chain, frame); frame->n_registers = script->n_registers; frame->registers = g_slice_alloc0 (sizeof (SwfdecAsValue) * frame->n_registers); if (script->constant_pool) { @@ -486,26 +553,16 @@ swfdec_as_frame_set_this (SwfdecAsFrame SwfdecAsObject * swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const char *variable) { - SwfdecAsScope *cur; - guint i; + GSList *walk; SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); g_return_val_if_fail (variable != NULL, NULL); - cur = frame->scope; - for (i = 0; i < 256; i++) { - if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), variable, &val)) - return SWFDEC_AS_OBJECT (cur); - if (cur->next == NULL) - break; - cur = cur->next; - } - if (i == 256) { - swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded"); - return NULL; + for (walk = frame->scope_chain; walk; walk = walk->next) { + if (swfdec_as_object_get_variable (walk->data, variable, &val)) + return SWFDEC_AS_OBJECT (walk->data); } - g_assert (SWFDEC_IS_AS_FRAME (cur)); /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target */ if (swfdec_as_object_get_variable (frame->target, variable, &val)) @@ -520,27 +577,17 @@ swfdec_as_frame_find_variable (SwfdecAsF SwfdecAsDeleteReturn swfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable) { - SwfdecAsScope *cur; - guint i; + GSList *walk; SwfdecAsDeleteReturn ret; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), FALSE); g_return_val_if_fail (variable != NULL, FALSE); - cur = frame->scope; - for (i = 0; i < 256; i++) { - ret = swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable); + for (walk = frame->scope_chain; walk; walk = walk->next) { + ret = swfdec_as_object_delete_variable (walk->data, variable); if (ret) return ret; - if (cur->next == NULL) - break; - cur = cur->next; - } - if (i == 256) { - swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded"); - return FALSE; } - g_assert (SWFDEC_IS_AS_FRAME (cur)); /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target set via SetTarget */ ret = swfdec_as_object_delete_variable (frame->target, variable); @@ -699,6 +746,10 @@ swfdec_as_frame_preload (SwfdecAsFrame * if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL && current_reg < script->n_registers) { SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], context->global); } + /*** add a default block that protects the program counter */ + swfdec_as_frame_push_block (frame, frame->script->buffer->data, + frame->script->buffer->data + frame->script->buffer->length, + (SwfdecAsFrameBlockFunc) swfdec_as_frame_return, NULL, NULL); out: if (context->debugger) { @@ -710,33 +761,6 @@ out: } /** - * swfdec_as_frame_check_scope: - * @frame: a #SwfdecAsFrame - * - * Checks that the current scope of the given @frame is still correct. - * If it is not, the current scope is popped and the next one is used. - * If the - **/ -void -swfdec_as_frame_check_scope (SwfdecAsFrame *frame) -{ - SwfdecAsScope *frame_scope; - - g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); - - frame_scope = SWFDEC_AS_SCOPE (frame); - while (frame->scope != frame_scope) { - SwfdecAsScope *cur = frame->scope; - - if (frame->pc >= cur->startpc && - frame->pc < cur->endpc) - break; - - frame->scope = cur->next; - } -} - -/** * swfdec_as_frame_get_next: * @frame: a #SwfdecAsFrame * diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h index 544d009..280f48a 100644 --- a/libswfdec/swfdec_as_frame_internal.h +++ b/libswfdec/swfdec_as_frame_internal.h @@ -20,14 +20,15 @@ #ifndef _SWFDEC_AS_FRAME_INTERNAL_H_ #define _SWFDEC_AS_FRAME_INTERNAL_H_ -#include <libswfdec/swfdec_as_scope.h> #include <libswfdec/swfdec_as_types.h> #include <libswfdec/swfdec_script_internal.h> G_BEGIN_DECLS +typedef void (* SwfdecAsFrameBlockFunc) (SwfdecAsFrame *frame, gpointer data); + struct _SwfdecAsFrame { - SwfdecAsScope scope_object; + SwfdecAsObject object; SwfdecAsFrame * next; /* next frame (FIXME: keep a list in the context instead?) */ SwfdecAsFunction * function; /* function we're executing or NULL if toplevel */ @@ -41,7 +42,10 @@ struct _SwfdecAsFrame { const char * function_name; /* name of function */ /* script execution */ SwfdecScript * script; /* script being executed */ - SwfdecAsScope * scope; /* first object in scope chain (either this frame or a with object) */ + GSList * scope_chain; /* the scope chain (with objects etc) */ + const guint8 * block_start; /* start of current block */ + const guint8 * block_end; /* end of current block */ + GArray * blocks; /* blocks we have entered (like With) */ SwfdecAsObject * target; /* target to use as last object in scope chain or for SetVariable */ SwfdecAsObject * original_target;/* original target (used when resetting target) */ gboolean is_local; /* TRUE if this frame takes local variables */ @@ -55,7 +59,7 @@ struct _SwfdecAsFrame { }; struct _SwfdecAsFrameClass { - SwfdecAsScopeClass scope_class; + SwfdecAsObjectClass object_class; }; SwfdecAsFrame * swfdec_as_frame_new (SwfdecAsContext * context, @@ -76,7 +80,14 @@ SwfdecAsDeleteReturn void swfdec_as_frame_set_target (SwfdecAsFrame * frame, SwfdecAsObject * target); -void swfdec_as_frame_check_scope (SwfdecAsFrame * frame); +void swfdec_as_frame_push_block (SwfdecAsFrame * frame, + const guint8 * start, + const guint8 * end, + SwfdecAsFrameBlockFunc func, + gpointer data, + GDestroyNotify destroy); +void swfdec_as_frame_pop_block (SwfdecAsFrame * frame); +void swfdec_as_frame_check_block (SwfdecAsFrame * frame); G_END_DECLS diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 564c35a..70f3c09 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -30,7 +30,6 @@ #include "swfdec_as_string.h" #include "swfdec_as_strings.h" #include "swfdec_as_super.h" -#include "swfdec_as_with.h" #include "swfdec_debug.h" #include <errno.h> @@ -1742,12 +1741,9 @@ swfdec_action_define_function (SwfdecAsC /* see function-scope tests */ if (cx->version > 5) { /* FIXME: or original target? */ - fun = swfdec_as_script_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame), frame->target, script); + fun = swfdec_as_script_function_new (frame->target, frame->scope_chain, script); } else { - SwfdecAsScope *scope = frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame); - while (scope->next) - scope = scope->next; - fun = swfdec_as_script_function_new (scope, frame->target, script); + fun = swfdec_as_script_function_new (frame->target, NULL, script); } if (fun == NULL) return; @@ -2264,6 +2260,14 @@ swfdec_action_mb_ascii_to_char_5 (Swfdec } static void +swfdec_action_pop_with (SwfdecAsFrame *frame, gpointer with_object) +{ + g_assert (frame->scope_chain->data == with_object); + frame->scope_chain = g_slist_delete_link (frame->scope_chain, frame->scope_chain); + swfdec_as_frame_pop_block (frame); +} + +static void swfdec_action_with (SwfdecAsContext *cx, guint action, const guint8 *data, guint len) { SwfdecAsObject *object; @@ -2280,7 +2284,9 @@ swfdec_action_with (SwfdecAsContext *cx, SWFDEC_INFO ("With called without an object, skipping"); cx->frame->pc = (guint8 *) data + len + offset; } else { - swfdec_as_with_new (object, data + len, offset); + cx->frame->scope_chain = g_slist_prepend (cx->frame->scope_chain, object); + swfdec_as_frame_push_block (cx->frame, data + len, data + len + offset, + swfdec_action_pop_with, object, NULL); } swfdec_as_stack_pop (cx); } diff --git a/libswfdec/swfdec_as_scope.c b/libswfdec/swfdec_as_scope.c deleted file mode 100644 index 1104b63..0000000 --- a/libswfdec/swfdec_as_scope.c +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 "swfdec_as_scope.h" -#include "swfdec_as_context.h" -#include "swfdec_debug.h" - -/** - * SwfdecAsScope: - * @see_also: #SwfdecAsFrame, #SwfdecAsWith - * - * A scope is the abstract base class for the #SwfdecAsWith and #SwfdecAsFrame - * classes. It is used to resolve variable references inside ActionScript. - * Consider the following simple ActionScript code: - * <informalexample><programlisting> - * foo = bar; - * </programlisting></informalexample> - * The variables foo and bar have to be resolved here, so that the script - * engine knows, what object to set them on. This is done by walking the scope - * chain. This chain is build up using With and Frame objects. - */ -G_DEFINE_ABSTRACT_TYPE (SwfdecAsScope, swfdec_as_scope, SWFDEC_TYPE_AS_OBJECT) - -static void -swfdec_as_scope_dispose (GObject *object) -{ - //SwfdecAsScope *scope = SWFDEC_AS_SCOPE (object); - - G_OBJECT_CLASS (swfdec_as_scope_parent_class)->dispose (object); -} - -static void -swfdec_as_scope_mark (SwfdecAsObject *object) -{ - SwfdecAsScope *scope = SWFDEC_AS_SCOPE (object); - - if (scope->next) - swfdec_as_object_mark (SWFDEC_AS_OBJECT (scope->next)); - - SWFDEC_AS_OBJECT_CLASS (swfdec_as_scope_parent_class)->mark (object); -} - -static void -swfdec_as_scope_class_init (SwfdecAsScopeClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); - - object_class->dispose = swfdec_as_scope_dispose; - - asobject_class->mark = swfdec_as_scope_mark; -} - -static void -swfdec_as_scope_init (SwfdecAsScope *scope) -{ -} - diff --git a/libswfdec/swfdec_as_scope.h b/libswfdec/swfdec_as_scope.h deleted file mode 100644 index 7c32e02..0000000 --- a/libswfdec/swfdec_as_scope.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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_SCOPE_H_ -#define _SWFDEC_AS_SCOPE_H_ - -#include <libswfdec/swfdec_as_object.h> -#include <libswfdec/swfdec_as_types.h> -#include <libswfdec/swfdec_script.h> - -G_BEGIN_DECLS - -typedef struct _SwfdecAsScopeClass SwfdecAsScopeClass; - -#define SWFDEC_TYPE_AS_SCOPE (swfdec_as_scope_get_type()) -#define SWFDEC_IS_AS_SCOPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_SCOPE)) -#define SWFDEC_IS_AS_SCOPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_SCOPE)) -#define SWFDEC_AS_SCOPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_SCOPE, SwfdecAsScope)) -#define SWFDEC_AS_SCOPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_SCOPE, SwfdecAsScopeClass)) -#define SWFDEC_AS_SCOPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_SCOPE, SwfdecAsScopeClass)) - -struct _SwfdecAsScope { - SwfdecAsObject object; - - /*< private >*/ - SwfdecAsScope * next; /* next scope or NULL if last */ - const guint8 * startpc; /* start of this scope */ - const guint8 * endpc; /* end of this scope */ -}; - -struct _SwfdecAsScopeClass { - SwfdecAsObjectClass object_class; -}; - -GType swfdec_as_scope_get_type (void); - - -G_END_DECLS -#endif diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c index 1abf45c..dc10056 100644 --- a/libswfdec/swfdec_as_script_function.c +++ b/libswfdec/swfdec_as_script_function.c @@ -40,7 +40,7 @@ swfdec_as_script_function_call (SwfdecAs frame = swfdec_as_frame_new (SWFDEC_AS_OBJECT (function)->context, script->script); if (frame == NULL) return NULL; - SWFDEC_AS_SCOPE (frame)->next = script->scope; + frame->scope_chain = g_slist_concat (frame->scope_chain, g_slist_copy (script->scope_chain)); frame->function = function; frame->target = script->target; frame->original_target = script->target; @@ -65,8 +65,7 @@ swfdec_as_script_function_mark (SwfdecAs { SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (object); - if (script->scope) - swfdec_as_object_mark (SWFDEC_AS_OBJECT (script->scope)); + g_slist_foreach (script->scope_chain, (GFunc) swfdec_as_object_mark, NULL); SWFDEC_AS_OBJECT_CLASS (swfdec_as_script_function_parent_class)->mark (object); } @@ -112,14 +111,13 @@ swfdec_as_script_function_init (SwfdecAs } SwfdecAsFunction * -swfdec_as_script_function_new (SwfdecAsScope *scope, SwfdecAsObject *target, SwfdecScript *script) +swfdec_as_script_function_new (SwfdecAsObject *target, const GSList *scope_chain, SwfdecScript *script) { SwfdecAsValue val; SwfdecAsScriptFunction *fun; SwfdecAsObject *proto; SwfdecAsContext *context; - g_return_val_if_fail (SWFDEC_IS_AS_SCOPE (scope), NULL); g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (target), NULL); g_return_val_if_fail (script != NULL, NULL); @@ -129,7 +127,7 @@ swfdec_as_script_function_new (SwfdecAsS fun = g_object_new (SWFDEC_TYPE_AS_SCRIPT_FUNCTION, NULL); if (fun == NULL) return NULL; - fun->scope = scope; + fun->scope_chain = g_slist_copy ((GSList *) scope_chain); fun->script = script; fun->target = target; swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsScriptFunction)); diff --git a/libswfdec/swfdec_as_script_function.h b/libswfdec/swfdec_as_script_function.h index 69f3481..c82aa62 100644 --- a/libswfdec/swfdec_as_script_function.h +++ b/libswfdec/swfdec_as_script_function.h @@ -42,7 +42,7 @@ struct _SwfdecAsScriptFunction { /* for script script_functions */ SwfdecScript * script; /* script being executed or NULL when native */ - SwfdecAsScope * scope; /* scope this script_function was defined in */ + GSList * scope_chain; /* scope this script_function was defined in */ SwfdecAsObject * target; /* target this object was defined in */ }; @@ -52,8 +52,8 @@ struct _SwfdecAsScriptFunctionClass { GType swfdec_as_script_function_get_type (void); -SwfdecAsFunction * swfdec_as_script_function_new (SwfdecAsScope * scope, - SwfdecAsObject * target, +SwfdecAsFunction * swfdec_as_script_function_new (SwfdecAsObject * target, + const GSList * scope_chain, SwfdecScript * script); diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c deleted file mode 100644 index 4484079..0000000 --- a/libswfdec/swfdec_as_with.c +++ /dev/null @@ -1,143 +0,0 @@ -/* 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 "swfdec_as_with.h" -#include "swfdec_as_context.h" -#include "swfdec_as_frame_internal.h" -#include "swfdec_debug.h" - -G_DEFINE_TYPE (SwfdecAsWith, swfdec_as_with, SWFDEC_TYPE_AS_SCOPE) - -static void -swfdec_as_with_mark (SwfdecAsObject *object) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - - swfdec_as_object_mark (with->object); - - SWFDEC_AS_OBJECT_CLASS (swfdec_as_with_parent_class)->mark (object); -} - -static SwfdecAsObject * -swfdec_as_with_resolve (SwfdecAsObject *object) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - - return with->object; -} - -static gboolean -swfdec_as_with_get (SwfdecAsObject *object, SwfdecAsObject *orig, - const char *variable, SwfdecAsValue *val, guint *flags) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - - if (orig != object) { - SWFDEC_FIXME ("write tests for this case"); - } - return swfdec_as_object_get_variable_and_flags (with->object, variable, val, flags, NULL); -} - -static void -swfdec_as_with_set (SwfdecAsObject *object, const char *variable, - const SwfdecAsValue *val, guint flags) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object); - - klass->set (with->object, variable, val, flags); -} - -static void -swfdec_as_with_set_flags (SwfdecAsObject *object, const char *variable, - guint flags, guint mask) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object); - - klass->set_flags (with->object, variable, flags, mask); -} - -static SwfdecAsDeleteReturn -swfdec_as_with_delete (SwfdecAsObject *object, const char *variable) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - - return swfdec_as_object_delete_variable (with->object, variable); -} - -static gboolean -swfdec_as_with_foreach (SwfdecAsObject *object, SwfdecAsVariableForeach func, - gpointer data) -{ - SwfdecAsWith *with = SWFDEC_AS_WITH (object); - SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object); - - return klass->foreach (with->object, func, data); -} - -static void -swfdec_as_with_class_init (SwfdecAsWithClass *klass) -{ - SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); - - asobject_class->mark = swfdec_as_with_mark; - asobject_class->get = swfdec_as_with_get; - asobject_class->set = swfdec_as_with_set; - asobject_class->set_flags = swfdec_as_with_set_flags; - asobject_class->del = swfdec_as_with_delete; - asobject_class->foreach = swfdec_as_with_foreach; - asobject_class->resolve = swfdec_as_with_resolve; -} - -static void -swfdec_as_with_init (SwfdecAsWith *with) -{ -} - -SwfdecAsScope * -swfdec_as_with_new (SwfdecAsObject *object, const guint8 *startpc, guint n_bytes) -{ - SwfdecAsContext *context; - SwfdecAsFrame *frame; - SwfdecAsScope *scope; - SwfdecAsWith *with; - - g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); - - context = object->context; - if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsWith))) - return NULL; - with = g_object_new (SWFDEC_TYPE_AS_WITH, NULL); - swfdec_as_object_add (SWFDEC_AS_OBJECT (with), context, sizeof (SwfdecAsWith)); - scope = SWFDEC_AS_SCOPE (with); - frame = context->frame; - with->object = object; - scope->startpc = startpc; - scope->endpc = startpc + n_bytes; - scope->next = frame->scope; - frame->scope = scope; - - return scope; -} - diff --git a/libswfdec/swfdec_as_with.h b/libswfdec/swfdec_as_with.h deleted file mode 100644 index 1d24d07..0000000 --- a/libswfdec/swfdec_as_with.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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_WITH_H_ -#define _SWFDEC_AS_WITH_H_ - -#include <libswfdec/swfdec_as_scope.h> -#include <libswfdec/swfdec_as_types.h> - -G_BEGIN_DECLS - -typedef struct _SwfdecAsWith SwfdecAsWith; -typedef struct _SwfdecAsWithClass SwfdecAsWithClass; - -#define SWFDEC_TYPE_AS_WITH (swfdec_as_with_get_type()) -#define SWFDEC_IS_AS_WITH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_WITH)) -#define SWFDEC_IS_AS_WITH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_WITH)) -#define SWFDEC_AS_WITH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_WITH, SwfdecAsWith)) -#define SWFDEC_AS_WITH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_WITH, SwfdecAsWithClass)) -#define SWFDEC_AS_WITH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_WITH, SwfdecAsWithClass)) - -struct _SwfdecAsWith { - SwfdecAsScope scope; - - /*< private >*/ - SwfdecAsObject * object; /* the object of this With context */ -}; - -struct _SwfdecAsWithClass { - SwfdecAsScopeClass scope_class; -}; - -GType swfdec_as_with_get_type (void); - -SwfdecAsScope * swfdec_as_with_new (SwfdecAsObject * object, - const guint8 * startpc, - guint n_bytes); - -G_END_DECLS -#endif
Possibly Parallel Threads
- Branch 'as' - 8 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_number.c libswfdec/swfdec_as_scope.h
- 3 commits - doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_boolean.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c
- Branch 'as' - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_native_function.h
- 15 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_super.c libswfdec/swfdec_as_with.c
- Branch 'as' - libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_script_function.c