diff options
author | Benjamin Otte <otte@gnome.org> | 2008-08-26 15:16:56 +0200 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2008-08-26 17:47:01 +0200 |
commit | b548964fb860095571c1a28cdca8b72f82f30543 (patch) | |
tree | faa81d9d6b1f6b753a97e8fe15d771ada799b5b6 | |
parent | 4dcba6e8e49fd209469945cbfd91793d23635d7f (diff) |
implement setslot and newactivation opcodes
-rw-r--r-- | swfdec/swfdec_abc_interpret.c | 29 | ||||
-rw-r--r-- | swfdec/swfdec_abc_traits.c | 25 | ||||
-rw-r--r-- | swfdec/swfdec_abc_traits.h | 2 |
3 files changed, 54 insertions, 2 deletions
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c index c892970b..59ca074c 100644 --- a/swfdec/swfdec_abc_interpret.c +++ b/swfdec/swfdec_abc_interpret.c @@ -1027,6 +1027,21 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope) val = swfdec_as_stack_peek (context, 1); SWFDEC_AS_VALUE_SET_INT (val, swfdec_abc_value_to_integer (context, val)); break; + case SWFDEC_ABC_OPCODE_NEW_ACTIVATION: + { + SwfdecAbcObject *object; + object = swfdec_abc_object_new (fun->activation, outer_scope); + if (fun->activation->construct) { + SwfdecAsValue tmp; + SWFDEC_AS_VALUE_SET_OBJECT (&tmp, SWFDEC_AS_OBJECT (object)); + if (!swfdec_abc_function_call (fun->activation->construct, + outer_scope, 0, &tmp, &tmp)) + break; + } + SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (context), + SWFDEC_AS_OBJECT (object)); + } + continue; case SWFDEC_ABC_OPCODE_NEW_CLASS: { SwfdecAbcClass *classp; @@ -1171,6 +1186,18 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope) !swfdec_abc_object_set_variable (context, swfdec_as_stack_pop (context), &mn, val)) break; continue; + case SWFDEC_ABC_OPCODE_SET_SLOT: + { + SwfdecAbcObject *object; + i = swfdec_bits_get_vu32 (&bits) - 1; + val = swfdec_as_stack_pop (context); + if (swfdec_abc_interpreter_throw_null (context, swfdec_as_stack_peek (context, 1))) + break; + object = SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_pop (context))); + swfdec_abc_traits_coerce (swfdec_abc_traits_get_slot_traits (object->traits, i), val); + object->slots[i] = *val; + } + continue; case SWFDEC_ABC_OPCODE_STRICT_EQUALS: { SwfdecAbcComparison comp; @@ -1256,7 +1283,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope) case SWFDEC_ABC_OPCODE_NEXT_NAME: case SWFDEC_ABC_OPCODE_NEXT_VALUE: case SWFDEC_ABC_OPCODE_NEW_ARRAY: - case SWFDEC_ABC_OPCODE_NEW_ACTIVATION: case SWFDEC_ABC_OPCODE_NEW_CATCH: case SWFDEC_ABC_OPCODE_NEW_OBJECT: case SWFDEC_ABC_OPCODE_NOP: @@ -1266,7 +1292,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope) case SWFDEC_ABC_OPCODE_RSHIFT: case SWFDEC_ABC_OPCODE_SEND_ENTER: case SWFDEC_ABC_OPCODE_SET_GLOBAL_SLOT: - case SWFDEC_ABC_OPCODE_SET_SLOT: case SWFDEC_ABC_OPCODE_SET_SUPER: case SWFDEC_ABC_OPCODE_SWEEP: case SWFDEC_ABC_OPCODE_THROW: diff --git a/swfdec/swfdec_abc_traits.c b/swfdec/swfdec_abc_traits.c index c924ad65..1e7deb96 100644 --- a/swfdec/swfdec_abc_traits.c +++ b/swfdec/swfdec_abc_traits.c @@ -442,3 +442,28 @@ swfdec_abc_traits_coerce (SwfdecAbcTraits *traits, SwfdecAsValue *val) return swfdec_abc_value_is_traits (val, traits); } +SwfdecAbcTraits * +swfdec_abc_traits_get_slot_traits (SwfdecAbcTraits *traits, guint slot) +{ + SwfdecAbcTrait *trait; + guint i, slot_id, const_id; + + g_return_val_if_fail (SWFDEC_IS_ABC_TRAITS (traits), NULL); + g_return_val_if_fail (traits->resolved, NULL); + g_return_val_if_fail (slot < traits->n_slots, NULL); + + while (traits->base && traits->base->n_slots > slot) + traits = traits->base; + + const_id = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_CONST, slot); + slot_id = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_SLOT, slot); + for (i = 0; i < traits->n_traits; i++) { + trait = &traits->traits[i]; + if (trait->type == slot_id || trait->type == const_id) + return trait->traits; + } + + g_assert_not_reached (); + return NULL; +} + diff --git a/swfdec/swfdec_abc_traits.h b/swfdec/swfdec_abc_traits.h index b69a6b48..13722aab 100644 --- a/swfdec/swfdec_abc_traits.h +++ b/swfdec/swfdec_abc_traits.h @@ -134,6 +134,8 @@ const SwfdecAbcTrait * swfdec_abc_traits_find_trait (SwfdecAbcTraits * traits, const char * name); const SwfdecAbcTrait * swfdec_abc_traits_find_trait_multi (SwfdecAbcTraits * traits, const SwfdecAbcMultiname *multi); +SwfdecAbcTraits * swfdec_abc_traits_get_slot_traits (SwfdecAbcTraits * traits, + guint slot); gboolean swfdec_abc_traits_is_traits (SwfdecAbcTraits * traits, SwfdecAbcTraits * parent); |