[Swfdec-commits] Branch 'abc' - 8 commits - swfdec/Makefile.am swfdec/swfdec_abc_function.c swfdec/swfdec_abc_global.c swfdec/swfdec_abc_interpret.c swfdec/swfdec_abc_multiname.c swfdec/swfdec_abc_multiname.h swfdec/swfdec_abc_object.c swfdec/swfdec_abc_object.h swfdec/swfdec_abc_pool.c swfdec/swfdec_abc_traits.c swfdec/swfdec_abc_traits.h swfdec/swfdec_abc_value.c swfdec/swfdec_abc_value.h swfdec/swfdec_as_types.c swfdec/swfdec_as_types.h swfdec/swfdec_sprite_movie.c
Benjamin Otte
company at kemper.freedesktop.org
Tue Aug 26 13:46:12 PDT 2008
swfdec/Makefile.am | 2
swfdec/swfdec_abc_function.c | 5
swfdec/swfdec_abc_global.c | 2
swfdec/swfdec_abc_interpret.c | 336 ++++++++++++++++++++++++++++++++------
swfdec/swfdec_abc_multiname.c | 17 +
swfdec/swfdec_abc_multiname.h | 6
swfdec/swfdec_abc_object.c | 95 ++++++++++
swfdec/swfdec_abc_object.h | 10 +
swfdec/swfdec_abc_pool.c | 17 -
swfdec/swfdec_abc_traits.c | 56 ++++--
swfdec/swfdec_abc_traits.h | 6
swfdec/swfdec_abc_value.c | 368 ++++++++++++++++++++++++++++++++++++++++++
swfdec/swfdec_abc_value.h | 64 +++++++
swfdec/swfdec_as_types.c | 34 ---
swfdec/swfdec_as_types.h | 6
swfdec/swfdec_sprite_movie.c | 2
16 files changed, 904 insertions(+), 122 deletions(-)
New commits:
commit 658f96fc119f9adbb07d81a57e6a82d9e8c24b50
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Aug 26 18:12:54 2008 +0200
implement construct and constructprop opcodes
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index 59ca074..bb64789 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -680,7 +680,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
swfdec_as_stack_push_n (context, argc);
if (opcode == SWFDEC_ABC_OPCODE_CALL_PROP_LEX)
SWFDEC_AS_VALUE_SET_NULL (val);
- if (!swfdec_abc_object_call_variable (context, &tmp, &mn, argc, val, &tmp))
+ if (!swfdec_abc_object_call_variable (context, &tmp, &mn, argc, val, val))
break;
swfdec_as_stack_pop_n (context, argc);
if (opcode == SWFDEC_ABC_OPCODE_CALL_PROP_VOID)
@@ -717,7 +717,37 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
SWFDEC_AS_VALUE_SET_STRING (val,
swfdec_abc_value_to_string (context, val));
}
- /* else NULL stays the same */
+ /* else NULL: it stays the same */
+ continue;
+ case SWFDEC_ABC_OPCODE_CONSTRUCT:
+ i = swfdec_bits_get_vu32 (&bits);
+ val = swfdec_as_stack_peek (context, i + 1);
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (val)) {
+ swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
+ "Instantiation attempted on a non-constructor.");
+ break;
+ }
+ if (!swfdec_abc_object_construct (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (val)),
+ i, val, val))
+ break;
+ swfdec_as_stack_pop_n (context, i);
+ continue;
+ case SWFDEC_ABC_OPCODE_CONSTRUCT_PROP:
+ {
+ SwfdecAsValue tmp;
+ guint argc;
+ i = swfdec_bits_get_vu32 (&bits);
+ argc = swfdec_bits_get_vu32 (&bits);
+ swfdec_as_stack_pop_n (context, argc);
+ if (!swfdec_abc_interpret_resolve_multiname (context, &mn, &pool->multinames[i]))
+ break;
+ val = swfdec_as_stack_peek (context, 1);
+ tmp = *val;
+ swfdec_as_stack_push_n (context, argc);
+ if (!swfdec_abc_object_construct_variable (context, &tmp, &mn, argc, val, val))
+ break;
+ swfdec_as_stack_pop_n (context, argc);
+ }
continue;
case SWFDEC_ABC_OPCODE_CONSTRUCT_SUPER:
i = swfdec_bits_get_vu32 (&bits);
@@ -1239,8 +1269,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_COERCE_I:
case SWFDEC_ABC_OPCODE_COERCE_U:
case SWFDEC_ABC_OPCODE_CONCAT:
- case SWFDEC_ABC_OPCODE_CONSTRUCT:
- case SWFDEC_ABC_OPCODE_CONSTRUCT_PROP:
case SWFDEC_ABC_OPCODE_CONVERT_B:
case SWFDEC_ABC_OPCODE_CONVERT_D:
case SWFDEC_ABC_OPCODE_CONVERT_I:
diff --git a/swfdec/swfdec_abc_object.c b/swfdec/swfdec_abc_object.c
index 5147fd8..d0597b3 100644
--- a/swfdec/swfdec_abc_object.c
+++ b/swfdec/swfdec_abc_object.c
@@ -377,7 +377,7 @@ swfdec_abc_object_init_variable (SwfdecAsContext *context, const SwfdecAsValue *
}
gboolean
-swfdec_abc_object_call_variable (SwfdecAsContext *context, const SwfdecAsValue *object,
+swfdec_abc_object_call_variable (SwfdecAsContext *context, const SwfdecAsValue *object,
const SwfdecAbcMultiname *mn, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
SwfdecAbcTraits *traits;
@@ -424,6 +424,23 @@ swfdec_abc_object_call_variable (SwfdecAsContext *context, const SwfdecAsValue *
}
gboolean
+swfdec_abc_object_construct_variable (SwfdecAsContext *context, const SwfdecAsValue *object,
+ const SwfdecAbcMultiname *mn, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+ SwfdecAsValue tmp;
+
+ if (!swfdec_abc_object_get_variable (context, object, mn, &tmp))
+ return FALSE;
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (&tmp)) {
+ swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
+ "Instantiation attempted on a non-constructor.");
+ return FALSE;
+ }
+ return swfdec_abc_object_construct (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (&tmp)),
+ argc, argv, ret);
+}
+
+gboolean
swfdec_abc_object_default_value (SwfdecAbcObject *object, SwfdecAsValue *default_value)
{
SwfdecAsContext *context;
diff --git a/swfdec/swfdec_abc_object.h b/swfdec/swfdec_abc_object.h
index 06395c4..683276d 100644
--- a/swfdec/swfdec_abc_object.h
+++ b/swfdec/swfdec_abc_object.h
@@ -92,6 +92,13 @@ gboolean swfdec_abc_object_call_variable (SwfdecAsContext * context,
guint argc,
SwfdecAsValue * argv,
SwfdecAsValue * ret);
+gboolean swfdec_abc_object_construct_variable
+ (SwfdecAsContext * context,
+ const SwfdecAsValue * object,
+ const SwfdecAbcMultiname * mn,
+ guint argc,
+ SwfdecAsValue * argv,
+ SwfdecAsValue * ret);
G_END_DECLS
commit 0976cee9297b4da790bd4bdafa294513295f3858
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Aug 26 18:12:37 2008 +0200
only coerce when the type is not any
diff --git a/swfdec/swfdec_abc_function.c b/swfdec/swfdec_abc_function.c
index b057a6b..2405c56 100644
--- a/swfdec/swfdec_abc_function.c
+++ b/swfdec/swfdec_abc_function.c
@@ -429,7 +429,7 @@ swfdec_abc_function_call (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *scope,
return FALSE;
for (i = 0; i <= MIN (argc, fun->n_args); i++) {
- if (!swfdec_abc_traits_coerce (fun->args[i].traits, &argv[i])) {
+ if (fun->args[i].traits && !swfdec_abc_traits_coerce (fun->args[i].traits, &argv[i])) {
swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
"Type Coercion failed: cannot convert %s to %s.",
swfdec_abc_value_get_type_name (&argv[i]), fun->args[i].traits->name);
commit 339b45171091c1de326ffead1360018d2037d3e0
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Aug 26 18:11:32 2008 +0200
handle exceptions properly
diff --git a/swfdec/swfdec_abc_traits.c b/swfdec/swfdec_abc_traits.c
index 1e7deb9..24cfc1a 100644
--- a/swfdec/swfdec_abc_traits.c
+++ b/swfdec/swfdec_abc_traits.c
@@ -402,15 +402,15 @@ swfdec_abc_traits_coerce (SwfdecAbcTraits *traits, SwfdecAsValue *val)
} else if (traits == SWFDEC_ABC_NUMBER_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
swfdec_abc_value_to_number (context, val));
- return TRUE;
+ return !context->exception;
} else if (traits == SWFDEC_ABC_INT_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_INT (val,
swfdec_abc_value_to_integer (context, val));
- return TRUE;
+ return !context->exception;
} else if (traits == SWFDEC_ABC_UINT_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
(guint) swfdec_abc_value_to_integer (context, val));
- return TRUE;
+ return !context->exception;
} else if (traits == SWFDEC_ABC_NUMBER_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
(guint) swfdec_abc_value_to_integer (context, val));
@@ -419,8 +419,10 @@ swfdec_abc_traits_coerce (SwfdecAbcTraits *traits, SwfdecAsValue *val)
if (SWFDEC_AS_VALUE_IS_UNDEFINED (val) || SWFDEC_AS_VALUE_IS_NULL (val)) {
SWFDEC_AS_VALUE_SET_NULL (val);
} else {
- SWFDEC_AS_VALUE_SET_STRING (val,
- swfdec_abc_value_to_string (context, val));
+ const char *s = swfdec_abc_value_to_string (context, val);
+ if (s == NULL)
+ return FALSE;
+ SWFDEC_AS_VALUE_SET_STRING (val, s);
}
return TRUE;
} else if (traits == SWFDEC_ABC_OBJECT_TRAITS (context)) {
commit b548964fb860095571c1a28cdca8b72f82f30543
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Aug 26 15:16:56 2008 +0200
implement setslot and newactivation opcodes
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index c892970..59ca074 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 c924ad6..1e7deb9 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 b69a6b4..13722aa 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);
commit 4dcba6e8e49fd209469945cbfd91793d23635d7f
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Aug 26 11:15:43 2008 +0200
split ABC value handling into its own file and implement a bunch of functions for it
diff --git a/swfdec/swfdec_abc_global.c b/swfdec/swfdec_abc_global.c
index afcea5f..517e103 100644
--- a/swfdec/swfdec_abc_global.c
+++ b/swfdec/swfdec_abc_global.c
@@ -315,7 +315,7 @@ swfdec_abc_global_get_builtin_class (SwfdecAbcGlobal *global, guint id)
traits = global->pool->instances[id];
- swfdec_abc_multiname_init (&mn, traits->name, traits->ns, NULL);
+ swfdec_abc_multiname_init (&mn, traits->ns, traits->name);
SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (global));
if (!swfdec_abc_object_get_variable (swfdec_gc_object_get_context (global),
&val, &mn, &val))
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index 2fb94f5..c892970 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -747,6 +747,17 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
val = swfdec_as_stack_peek (context, 1);
*swfdec_as_stack_push (context) = *val;
continue;
+ case SWFDEC_ABC_OPCODE_EQUALS:
+ {
+ SwfdecAbcComparison comp;
+ val = swfdec_as_stack_peek (context, 2);
+ comp = swfdec_abc_value_equals (context, val, swfdec_as_stack_pop (context));
+ if (comp == SWFDEC_ABC_COMPARE_THROWN)
+ break;
+ g_assert (comp == SWFDEC_ABC_COMPARE_EQUAL || comp == SWFDEC_ABC_COMPARE_NOT_EQUAL);
+ SWFDEC_AS_VALUE_SET_BOOLEAN (val, comp == SWFDEC_ABC_COMPARE_EQUAL);
+ }
+ continue;
case SWFDEC_ABC_OPCODE_FIND_PROP_STRICT:
case SWFDEC_ABC_OPCODE_FIND_PROPERTY:
i = swfdec_bits_get_vu32 (&bits);
@@ -819,6 +830,150 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
break;
*val = SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (val))->slots[i - 1];
continue;
+ case SWFDEC_ABC_OPCODE_IFEQ:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_equals (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_EQUAL && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFFALSE:
+ i = swfdec_bits_get_s24 (&bits);
+ if (!swfdec_as_value_to_boolean (context, swfdec_as_stack_pop (context)) &&
+ !swfdec_abc_interpret_jump (context, &bits, i))
+ break;
+ continue;
+ case SWFDEC_ABC_OPCODE_IFGE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp != SWFDEC_ABC_COMPARE_GREATER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFGT:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, val, swfdec_as_stack_pop (context));
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_LOWER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFLE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, val, swfdec_as_stack_pop (context));
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_GREATER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFLT:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_LOWER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFNE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_equals (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_NOT_EQUAL && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFNLE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, val, swfdec_as_stack_pop (context));
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp != SWFDEC_ABC_COMPARE_GREATER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFNLT:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp != SWFDEC_ABC_COMPARE_LOWER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFNGE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp != SWFDEC_ABC_COMPARE_GREATER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFNGT:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_compare (context, val, swfdec_as_stack_pop (context));
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp != SWFDEC_ABC_COMPARE_LOWER && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFSTRICTEQ:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_strict_equals (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_EQUAL && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFSTRICTNE:
+ {
+ SwfdecAbcComparison comp;
+ i = swfdec_bits_get_s24 (&bits);
+ val = swfdec_as_stack_pop (context);
+ comp = swfdec_abc_value_strict_equals (context, swfdec_as_stack_pop (context), val);
+ if (comp == SWFDEC_ABC_COMPARE_THROWN ||
+ (comp == SWFDEC_ABC_COMPARE_NOT_EQUAL && !swfdec_abc_interpret_jump (context, &bits, i)))
+ break;
+ }
+ continue;
+ case SWFDEC_ABC_OPCODE_IFTRUE:
+ i = swfdec_bits_get_s24 (&bits);
+ if (swfdec_as_value_to_boolean (context, swfdec_as_stack_pop (context)) &&
+ !swfdec_abc_interpret_jump (context, &bits, i))
+ break;
+ continue;
case SWFDEC_ABC_OPCODE_INIT_PROPERTY:
{
SwfdecAbcTraits *traits;
@@ -1016,6 +1171,15 @@ 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_STRICT_EQUALS:
+ {
+ SwfdecAbcComparison comp;
+ val = swfdec_as_stack_peek (context, 2);
+ comp = swfdec_abc_value_strict_equals (context, val, swfdec_as_stack_pop (context));
+ g_assert (comp == SWFDEC_ABC_COMPARE_EQUAL || comp == SWFDEC_ABC_COMPARE_NOT_EQUAL);
+ SWFDEC_AS_VALUE_SET_BOOLEAN (val, comp == SWFDEC_ABC_COMPARE_EQUAL);
+ }
+ continue;
case SWFDEC_ABC_OPCODE_SWAP:
{
SwfdecAsValue tmp = *swfdec_as_stack_peek (context, 1);
@@ -1065,7 +1229,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_DOUBLE_TO_ATOM:
case SWFDEC_ABC_OPCODE_DXNS:
case SWFDEC_ABC_OPCODE_DXNS_LATE:
- case SWFDEC_ABC_OPCODE_EQUALS:
case SWFDEC_ABC_OPCODE_ESC_XATTR:
case SWFDEC_ABC_OPCODE_ESC_XELEM:
case SWFDEC_ABC_OPCODE_FIND_DEF:
@@ -1076,20 +1239,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_GREATER_THAN:
case SWFDEC_ABC_OPCODE_HAS_NEXT:
case SWFDEC_ABC_OPCODE_HAS_NEXT2:
- case SWFDEC_ABC_OPCODE_IFEQ:
- case SWFDEC_ABC_OPCODE_IFFALSE:
- case SWFDEC_ABC_OPCODE_IFGE:
- case SWFDEC_ABC_OPCODE_IFGT:
- case SWFDEC_ABC_OPCODE_IFLE:
- case SWFDEC_ABC_OPCODE_IFLT:
- case SWFDEC_ABC_OPCODE_IFNE:
- case SWFDEC_ABC_OPCODE_IFNLE:
- case SWFDEC_ABC_OPCODE_IFNLT:
- case SWFDEC_ABC_OPCODE_IFNGE:
- case SWFDEC_ABC_OPCODE_IFNGT:
- case SWFDEC_ABC_OPCODE_IFSTRICTEQ:
- case SWFDEC_ABC_OPCODE_IFSTRICTNE:
- case SWFDEC_ABC_OPCODE_IFTRUE:
case SWFDEC_ABC_OPCODE_IN:
case SWFDEC_ABC_OPCODE_INC_LOCAL:
case SWFDEC_ABC_OPCODE_INCLOCAL_I:
@@ -1119,7 +1268,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_SET_GLOBAL_SLOT:
case SWFDEC_ABC_OPCODE_SET_SLOT:
case SWFDEC_ABC_OPCODE_SET_SUPER:
- case SWFDEC_ABC_OPCODE_STRICT_EQUALS:
case SWFDEC_ABC_OPCODE_SWEEP:
case SWFDEC_ABC_OPCODE_THROW:
case SWFDEC_ABC_OPCODE_TIMESTAMP:
diff --git a/swfdec/swfdec_abc_multiname.c b/swfdec/swfdec_abc_multiname.c
index 346fce6..e7de0ac 100644
--- a/swfdec/swfdec_abc_multiname.c
+++ b/swfdec/swfdec_abc_multiname.c
@@ -30,15 +30,26 @@
#include "swfdec_debug.h"
void
-swfdec_abc_multiname_init (SwfdecAbcMultiname *multi, const char *name,
- SwfdecAbcNamespace *ns, SwfdecAbcNsSet *set)
+swfdec_abc_multiname_init (SwfdecAbcMultiname *multi, SwfdecAbcNamespace *ns,
+ const char *name)
{
g_return_if_fail (multi != NULL);
- g_return_if_fail (ns == NULL || set == NULL);
g_return_if_fail (ns == NULL || ns == SWFDEC_ABC_MULTINAME_ANY || SWFDEC_IS_ABC_NAMESPACE (ns));
multi->name = name;
multi->ns = ns;
+ multi->nsset = NULL;
+}
+
+void
+swfdec_abc_multiname_init_set (SwfdecAbcMultiname *multi, SwfdecAbcNsSet *set,
+ const char *name)
+{
+ g_return_if_fail (multi != NULL);
+ g_return_if_fail (set != NULL);
+
+ multi->name = name;
+ multi->ns = NULL;
multi->nsset = set;
}
diff --git a/swfdec/swfdec_abc_multiname.h b/swfdec/swfdec_abc_multiname.h
index 4ed3186..e2c5bc7 100644
--- a/swfdec/swfdec_abc_multiname.h
+++ b/swfdec/swfdec_abc_multiname.h
@@ -35,9 +35,11 @@ struct _SwfdecAbcMultiname {
};
void swfdec_abc_multiname_init (SwfdecAbcMultiname * multi,
- const char * name,
SwfdecAbcNamespace * ns,
- SwfdecAbcNsSet * set);
+ const char * name);
+void swfdec_abc_multiname_init_set (SwfdecAbcMultiname * multi,
+ SwfdecAbcNsSet * set,
+ const char * name);
void swfdec_abc_multiname_init_from_string (SwfdecAbcMultiname * multi,
SwfdecAsContext * context,
const char * string);
diff --git a/swfdec/swfdec_abc_object.c b/swfdec/swfdec_abc_object.c
index 3216505..5147fd8 100644
--- a/swfdec/swfdec_abc_object.c
+++ b/swfdec/swfdec_abc_object.c
@@ -29,7 +29,9 @@
#include "swfdec_abc_multiname.h"
#include "swfdec_abc_scope_chain.h"
#include "swfdec_abc_traits.h"
+#include "swfdec_abc_value.h"
#include "swfdec_as_context.h"
+#include "swfdec_as_strings.h"
#include "swfdec_debug.h"
enum {
@@ -420,3 +422,71 @@ swfdec_abc_object_call_variable (SwfdecAsContext *context, const SwfdecAsValue *
}
}
}
+
+gboolean
+swfdec_abc_object_default_value (SwfdecAbcObject *object, SwfdecAsValue *default_value)
+{
+ SwfdecAsContext *context;
+ SwfdecAbcMultiname mn;
+ SwfdecAsValue val;
+
+ g_return_val_if_fail (SWFDEC_IS_ABC_OBJECT (object), FALSE);
+ g_return_val_if_fail (default_value != NULL, FALSE);
+
+ context = swfdec_gc_object_get_context (object);
+
+ /* first, call toString - if it returns a primitive, return it */
+ swfdec_abc_multiname_init (&mn, context->public_ns, SWFDEC_AS_STR_valueOf);
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (object));
+ if (!swfdec_abc_object_call_variable (context, &val, &mn, 0, &val, default_value))
+ return FALSE;
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (default_value))
+ return TRUE;
+
+ /* second, call valueOf - if it returns a primitive, return it */
+ swfdec_abc_multiname_init (&mn, context->public_ns, SWFDEC_AS_STR_toString);
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (object));
+ if (!swfdec_abc_object_call_variable (context, &val, &mn, 0, &val, default_value))
+ return FALSE;
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (default_value))
+ return TRUE;
+
+ /* Object doesn't want to be a string, complain */
+ swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
+ "Cannot convert %s to primitive.", object->traits->name);
+ SWFDEC_AS_VALUE_SET_UNDEFINED (default_value);
+ return FALSE;
+}
+
+const char *
+swfdec_abc_object_to_string (SwfdecAbcObject *object)
+{
+ SwfdecAsContext *context;
+ SwfdecAbcMultiname mn;
+ SwfdecAsValue val, ret;
+
+ g_return_val_if_fail (SWFDEC_IS_ABC_OBJECT (object), FALSE);
+
+ context = swfdec_gc_object_get_context (object);
+
+ /* first, call toString - if it returns a primitive, return it */
+ swfdec_abc_multiname_init (&mn, context->public_ns, SWFDEC_AS_STR_toString);
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (object));
+ if (!swfdec_abc_object_call_variable (context, &val, &mn, 0, &val, &ret))
+ return NULL;
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (&ret))
+ return swfdec_abc_value_to_string (context, &ret);
+
+ /* second, call valueOf - if it returns a primitive, return it */
+ swfdec_abc_multiname_init (&mn, context->public_ns, SWFDEC_AS_STR_valueOf);
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (object));
+ if (!swfdec_abc_object_call_variable (context, &val, &mn, 0, &val, &ret))
+ return NULL;
+ if (!SWFDEC_AS_VALUE_IS_OBJECT (&ret))
+ return swfdec_abc_value_to_string (context, &ret);
+
+ /* Object doesn't want to be a string, complain */
+ swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
+ "Cannot convert %s to primitive.", object->traits->name);
+ return NULL;
+}
diff --git a/swfdec/swfdec_abc_object.h b/swfdec/swfdec_abc_object.h
index 70f81fb..06395c4 100644
--- a/swfdec/swfdec_abc_object.h
+++ b/swfdec/swfdec_abc_object.h
@@ -64,8 +64,7 @@ SwfdecAbcObject * swfdec_abc_object_new_from_class(SwfdecAbcClass * classp);
gboolean swfdec_abc_object_default_value (SwfdecAbcObject * object,
SwfdecAsValue * default_value);
-gboolean swfdec_abc_object_to_string (SwfdecAbcObject * object,
- SwfdecAsValue * string);
+const char * swfdec_abc_object_to_string (SwfdecAbcObject * object);
gboolean swfdec_abc_object_call (SwfdecAbcObject * object,
guint argc,
SwfdecAsValue * argv,
diff --git a/swfdec/swfdec_abc_pool.c b/swfdec/swfdec_abc_pool.c
index dbd9422..176ce41 100644
--- a/swfdec/swfdec_abc_pool.c
+++ b/swfdec/swfdec_abc_pool.c
@@ -335,9 +335,8 @@ swfdec_abc_pool_parse_constants (SwfdecAbcPool *pool, SwfdecBits *bits)
if (nameid >= pool->n_strings)
THROW (pool, "Cpool index %u is out of range %u.", nameid, pool->n_strings);
swfdec_abc_multiname_init (&pool->multinames[i],
- nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
nsid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->namespaces[nsid],
- NULL);
+ nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid]);
break;
case 0x10:
SWFDEC_FIXME ("implement attributes");
@@ -346,14 +345,14 @@ swfdec_abc_pool_parse_constants (SwfdecAbcPool *pool, SwfdecBits *bits)
if (nameid >= pool->n_strings)
THROW (pool, "Cpool index %u is out of range %u.", nameid, pool->n_strings);
swfdec_abc_multiname_init (&pool->multinames[i],
- nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
- NULL, NULL);
+ NULL,
+ nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid]);
break;
case 0x12:
SWFDEC_FIXME ("implement attributes");
case 0x11:
swfdec_abc_multiname_init (&pool->multinames[i],
- NULL, NULL, NULL);
+ NULL, NULL);
break;
case 0x0E:
SWFDEC_FIXME ("implement attributes");
@@ -364,9 +363,8 @@ swfdec_abc_pool_parse_constants (SwfdecAbcPool *pool, SwfdecBits *bits)
READ_U30 (nsid, bits);
if (nsid >= pool->n_nssets)
THROW (pool, "Cpool index %u is out of range %u.", nsid, pool->n_nssets);
- swfdec_abc_multiname_init (&pool->multinames[i],
- nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
- NULL, pool->nssets[nsid]);
+ swfdec_abc_multiname_init_set (&pool->multinames[i], pool->nssets[nsid],
+ nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid]);
break;
case 0x1C:
SWFDEC_FIXME ("implement attributes");
@@ -374,8 +372,7 @@ swfdec_abc_pool_parse_constants (SwfdecAbcPool *pool, SwfdecBits *bits)
READ_U30 (nsid, bits);
if (nsid >= pool->n_nssets)
THROW (pool, "Cpool index %u is out of range %u.", nsid, pool->n_nssets);
- swfdec_abc_multiname_init (&pool->multinames[i],
- NULL, NULL, pool->nssets[nsid]);
+ swfdec_abc_multiname_init_set (&pool->multinames[i], pool->nssets[nsid], NULL);
break;
default:
THROW (pool, "Cpool entry %u is wrong type.", i);
diff --git a/swfdec/swfdec_abc_value.c b/swfdec/swfdec_abc_value.c
index dc58fc6..e36c4dc 100644
--- a/swfdec/swfdec_abc_value.c
+++ b/swfdec/swfdec_abc_value.c
@@ -119,7 +119,7 @@ swfdec_abc_value_to_number (SwfdecAsContext *context, const SwfdecAsValue *value
gboolean
swfdec_abc_value_to_primitive (SwfdecAsValue *dest, const SwfdecAsValue *src)
{
- g_return_val_if_fail (SWFDEC_IS_AS_VALUE (dest), FALSE);
+ g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (SWFDEC_IS_AS_VALUE (src), FALSE);
if (SWFDEC_AS_VALUE_IS_OBJECT (src)) {
@@ -149,13 +149,7 @@ swfdec_abc_value_to_string (SwfdecAsContext *context, const SwfdecAsValue *value
case SWFDEC_AS_TYPE_STRING:
return SWFDEC_AS_VALUE_GET_STRING (value);
case SWFDEC_AS_TYPE_OBJECT:
- {
- SwfdecAsValue tmp;
- if (!swfdec_abc_object_to_string (
- SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (value)), &tmp))
- return SWFDEC_AS_STR_EMPTY;
- return swfdec_abc_value_to_string (context, &tmp);
- }
+ return swfdec_abc_object_to_string (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (value)));
case SWFDEC_AS_TYPE_NAMESPACE:
return SWFDEC_AS_VALUE_GET_NAMESPACE (value)->uri;
case SWFDEC_AS_TYPE_INT:
@@ -222,6 +216,8 @@ swfdec_abc_value_compare (SwfdecAsContext *context, const SwfdecAsValue *lval,
!swfdec_abc_value_to_primitive (&rtmp, rval))
return SWFDEC_ABC_COMPARE_THROWN;
+ /* FIXME: need special code for XMLList here */
+
if (SWFDEC_AS_VALUE_IS_STRING (<mp) && SWFDEC_AS_VALUE_IS_STRING (&rtmp)) {
int comp = strcmp (SWFDEC_AS_VALUE_GET_STRING (<mp),
SWFDEC_AS_VALUE_GET_STRING (&rtmp));
@@ -238,3 +234,135 @@ swfdec_abc_value_compare (SwfdecAsContext *context, const SwfdecAsValue *lval,
}
}
+SwfdecAbcComparison
+swfdec_abc_value_equals (SwfdecAsContext *context, const SwfdecAsValue *lval,
+ const SwfdecAsValue *rval)
+{
+ SwfdecAsValue tmp;
+ SwfdecAsValueType ltype, rtype;
+
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (lval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (rval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+
+ ltype = SWFDEC_AS_VALUE_GET_TYPE (lval);
+ rtype = SWFDEC_AS_VALUE_GET_TYPE (rval);
+
+ /* FIXME: need special code for XMLList here */
+
+ if (ltype == rtype) {
+ switch (ltype) {
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ case SWFDEC_AS_TYPE_NULL:
+ return SWFDEC_ABC_COMPARE_EQUAL;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_VALUE_GET_BOOLEAN (lval) == SWFDEC_AS_VALUE_GET_BOOLEAN (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_NUMBER:
+ return SWFDEC_AS_VALUE_GET_NUMBER (lval) == SWFDEC_AS_VALUE_GET_NUMBER (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_STRING:
+ return SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_OBJECT:
+ /* FIXME: Need special code for QName and XMLList here */
+ return SWFDEC_AS_VALUE_GET_OBJECT (lval) == SWFDEC_AS_VALUE_GET_OBJECT (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return swfdec_abc_namespace_equal (SWFDEC_AS_VALUE_GET_NAMESPACE (lval),
+ SWFDEC_AS_VALUE_GET_NAMESPACE (rval)) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return SWFDEC_ABC_COMPARE_UNDEFINED;
+ }
+ }
+
+ if ((ltype == SWFDEC_AS_TYPE_UNDEFINED && rtype == SWFDEC_AS_TYPE_NULL) ||
+ (ltype == SWFDEC_AS_TYPE_NULL && rtype == SWFDEC_AS_TYPE_UNDEFINED))
+ return SWFDEC_ABC_COMPARE_EQUAL;
+
+ if (ltype == SWFDEC_AS_TYPE_NUMBER && rtype == SWFDEC_AS_TYPE_STRING) {
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, rval));
+ return swfdec_abc_value_equals (context, lval, &tmp);
+ }
+ if (ltype == SWFDEC_AS_TYPE_STRING && rtype == SWFDEC_AS_TYPE_NUMBER) {
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, lval));
+ return swfdec_abc_value_equals (context, &tmp, rval);
+ }
+
+ /* FIXME: need special code for XMLList here */
+
+ if (ltype == SWFDEC_AS_TYPE_BOOLEAN) {
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, lval));
+ return swfdec_abc_value_equals (context, &tmp, rval);
+ }
+ if (rtype == SWFDEC_AS_TYPE_BOOLEAN) {
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, rval));
+ return swfdec_abc_value_equals (context, lval, &tmp);
+ }
+
+ if (rtype == SWFDEC_AS_TYPE_OBJECT &&
+ (ltype == SWFDEC_AS_TYPE_NUMBER || ltype == SWFDEC_AS_TYPE_STRING)) {
+ if (!swfdec_abc_object_default_value (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (rval)), &tmp))
+ return SWFDEC_ABC_COMPARE_THROWN;
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, rval));
+ return swfdec_abc_value_equals (context, lval, &tmp);
+ }
+ if (ltype == SWFDEC_AS_TYPE_OBJECT &&
+ (rtype == SWFDEC_AS_TYPE_NUMBER || rtype == SWFDEC_AS_TYPE_STRING)) {
+ if (!swfdec_abc_object_default_value (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (lval)), &tmp))
+ return SWFDEC_ABC_COMPARE_THROWN;
+ SWFDEC_AS_VALUE_SET_NUMBER (&tmp, swfdec_abc_value_to_number (context, lval));
+ return swfdec_abc_value_equals (context, &tmp, rval);
+ }
+
+ return SWFDEC_ABC_COMPARE_NOT_EQUAL;
+}
+
+SwfdecAbcComparison
+swfdec_abc_value_strict_equals (SwfdecAsContext *context, const SwfdecAsValue *lval,
+ const SwfdecAsValue *rval)
+{
+ SwfdecAsValueType ltype, rtype;
+
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (lval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (rval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+
+ ltype = SWFDEC_AS_VALUE_GET_TYPE (lval);
+ rtype = SWFDEC_AS_VALUE_GET_TYPE (rval);
+
+ /* FIXME: need special code for XMLList here */
+
+ if (ltype == rtype) {
+ switch (ltype) {
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ case SWFDEC_AS_TYPE_NULL:
+ return SWFDEC_ABC_COMPARE_EQUAL;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_VALUE_GET_BOOLEAN (lval) == SWFDEC_AS_VALUE_GET_BOOLEAN (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_NUMBER:
+ return SWFDEC_AS_VALUE_GET_NUMBER (lval) == SWFDEC_AS_VALUE_GET_NUMBER (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_STRING:
+ return SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_OBJECT:
+ /* FIXME: Need special code for XMLList here */
+ return SWFDEC_AS_VALUE_GET_OBJECT (lval) == SWFDEC_AS_VALUE_GET_OBJECT (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return SWFDEC_AS_VALUE_GET_NAMESPACE (lval) == SWFDEC_AS_VALUE_GET_NAMESPACE (rval) ?
+ SWFDEC_ABC_COMPARE_EQUAL : SWFDEC_ABC_COMPARE_NOT_EQUAL;
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return SWFDEC_ABC_COMPARE_UNDEFINED;
+ }
+ }
+ return SWFDEC_ABC_COMPARE_NOT_EQUAL;
+}
+
diff --git a/swfdec/swfdec_abc_value.h b/swfdec/swfdec_abc_value.h
index dfccd87..f6b9ee1 100644
--- a/swfdec/swfdec_abc_value.h
+++ b/swfdec/swfdec_abc_value.h
@@ -28,10 +28,11 @@ G_BEGIN_DECLS
typedef enum {
SWFDEC_ABC_COMPARE_UNDEFINED,
+ SWFDEC_ABC_COMPARE_NOT_EQUAL = SWFDEC_ABC_COMPARE_UNDEFINED,
SWFDEC_ABC_COMPARE_THROWN,
SWFDEC_ABC_COMPARE_LOWER,
SWFDEC_ABC_COMPARE_EQUAL,
- SWFDEC_ABC_COMPARE_GREATER
+ SWFDEC_ABC_COMPARE_GREATER,
} SwfdecAbcComparison;
gboolean swfdec_abc_value_to_boolean (SwfdecAsContext * context,
@@ -51,6 +52,12 @@ const char * swfdec_abc_value_get_type_name (const SwfdecAsValue * value);
SwfdecAbcComparison swfdec_abc_value_compare (SwfdecAsContext * context,
const SwfdecAsValue * lval,
const SwfdecAsValue * rval);
+SwfdecAbcComparison swfdec_abc_value_equals (SwfdecAsContext * context,
+ const SwfdecAsValue * lval,
+ const SwfdecAsValue * rval);
+SwfdecAbcComparison swfdec_abc_value_strict_equals (SwfdecAsContext * context,
+ const SwfdecAsValue * lval,
+ const SwfdecAsValue * rval);
G_END_DECLS
commit 99fc769d0a73d48f7190e316d426dec1488cd1ac
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Aug 25 13:15:30 2008 +0200
add a seperate header for ABC functions on SwfdecAsValue
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 6844454..21e5355 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -23,6 +23,7 @@ libswfdec_source_files = \
swfdec_abc_scope_chain.c \
swfdec_abc_script.c \
swfdec_abc_traits.c \
+ swfdec_abc_value.c \
swfdec_access.c \
swfdec_accessibility.c \
swfdec_actor.c \
@@ -257,6 +258,7 @@ noinst_HEADERS = \
swfdec_abc_script.h \
swfdec_abc_traits.h \
swfdec_abc_types.h \
+ swfdec_abc_value.h \
swfdec_access.h \
swfdec_actor.h \
swfdec_amf.h \
diff --git a/swfdec/swfdec_abc_function.c b/swfdec/swfdec_abc_function.c
index d0e58d6..b057a6b 100644
--- a/swfdec/swfdec_abc_function.c
+++ b/swfdec/swfdec_abc_function.c
@@ -28,6 +28,7 @@
#include "swfdec_abc_internal.h"
#include "swfdec_abc_interpret.h"
#include "swfdec_abc_traits.h"
+#include "swfdec_abc_value.h"
#include "swfdec_as_context.h"
#include "swfdec_as_frame_internal.h"
#include "swfdec_as_strings.h" /* swfdec_abc_function_describe */
@@ -431,7 +432,7 @@ swfdec_abc_function_call (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *scope,
if (!swfdec_abc_traits_coerce (fun->args[i].traits, &argv[i])) {
swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_TYPE_ERROR,
"Type Coercion failed: cannot convert %s to %s.",
- swfdec_as_value_get_type_name (&argv[i]), fun->args[i].traits->name);
+ swfdec_abc_value_get_type_name (&argv[i]), fun->args[i].traits->name);
return FALSE;
}
}
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index 7413056..2fb94f5 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -32,6 +32,7 @@
#include "swfdec_abc_scope_chain.h"
#include "swfdec_abc_script.h"
#include "swfdec_abc_traits.h"
+#include "swfdec_abc_value.h"
#include "swfdec_as_context.h"
#include "swfdec_as_frame_internal.h"
#include "swfdec_as_internal.h"
@@ -246,7 +247,7 @@ swfdec_abc_interpret_resolve_multiname (SwfdecAsContext *context,
SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (val))->traits == SWFDEC_ABC_QNAME_TRAITS (context)) {
SWFDEC_FIXME ("implement Qname multiname resolution");
}
- target->name = swfdec_as_value_to_string (context, val);
+ target->name = swfdec_abc_value_to_string (context, val);
} else {
target->name = source->name;
}
@@ -324,7 +325,7 @@ swfdec_as_value_has_property (SwfdecAsContext *context, const SwfdecAsValue *val
if (SWFDEC_AS_VALUE_IS_OBJECT (value)) {
o = SWFDEC_AS_VALUE_GET_OBJECT (value);
} else {
- traits = swfdec_as_value_to_traits (context, value);
+ traits = swfdec_abc_value_to_traits (context, value);
if (swfdec_abc_traits_find_trait_multi (traits, mn))
return TRUE;
o = swfdec_as_value_to_prototype (context, value);
@@ -626,8 +627,8 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
SwfdecAbcTraits *ltraits, *rtraits;
rhs = swfdec_as_stack_pop (context);
lhs = swfdec_as_stack_peek (context, 1);
- ltraits = swfdec_as_value_to_traits (context, lhs);
- rtraits = swfdec_as_value_to_traits (context, rhs);
+ ltraits = swfdec_abc_value_to_traits (context, lhs);
+ rtraits = swfdec_abc_value_to_traits (context, rhs);
if (SWFDEC_AS_VALUE_IS_NUMBER (lhs) && SWFDEC_AS_VALUE_IS_NUMBER (rhs)) {
SWFDEC_AS_VALUE_SET_NUMBER (lhs,
SWFDEC_AS_VALUE_GET_NUMBER (lhs) + SWFDEC_AS_VALUE_GET_NUMBER (rhs));
@@ -636,8 +637,8 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
(ltraits == SWFDEC_ABC_DATE_TRAITS (context)) ||
(rtraits == SWFDEC_ABC_DATE_TRAITS (context))) {
SWFDEC_AS_VALUE_SET_STRING (lhs, swfdec_as_str_concat (context,
- swfdec_as_value_to_string (context, lhs),
- swfdec_as_value_to_string (context, rhs)));
+ swfdec_abc_value_to_string (context, lhs),
+ swfdec_abc_value_to_string (context, rhs)));
continue;
}
if ((ltraits == SWFDEC_ABC_XML_TRAITS (context) || ltraits == SWFDEC_ABC_XML_LIST_TRAITS (context)) &&
@@ -650,18 +651,18 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
swfdec_as_value_to_primitive (&rtmp);
if (SWFDEC_AS_VALUE_IS_STRING (<mp) || SWFDEC_AS_VALUE_IS_STRING (&rtmp)) {
SWFDEC_AS_VALUE_SET_STRING (lhs, swfdec_as_str_concat (context,
- swfdec_as_value_to_string (context, <mp),
- swfdec_as_value_to_string (context, &rtmp)));
+ swfdec_abc_value_to_string (context, <mp),
+ swfdec_abc_value_to_string (context, &rtmp)));
} else {
SWFDEC_AS_VALUE_SET_NUMBER (lhs,
- swfdec_as_value_to_number (context, lhs) + swfdec_as_value_to_number (context, rhs));
+ swfdec_abc_value_to_number (context, lhs) + swfdec_abc_value_to_number (context, rhs));
}
}
continue;
case SWFDEC_ABC_OPCODE_ADD_I:
val = swfdec_as_stack_peek (context, 2);
- SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) +
- swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_abc_value_to_integer (context, val) +
+ swfdec_abc_value_to_integer (context, swfdec_as_stack_pop (context)));
break;
case SWFDEC_ABC_OPCODE_CALL_PROPERTY:
case SWFDEC_ABC_OPCODE_CALL_PROP_LEX:
@@ -696,7 +697,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
if (!swfdec_abc_traits_coerce (traits, val)) {
swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_REFERENCE_ERROR,
"Type Coercion failed: cannot convert %s to %s.",
- swfdec_as_value_get_type_name (val), traits->name);
+ swfdec_abc_value_get_type_name (val), traits->name);
break;
}
}
@@ -714,7 +715,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
SWFDEC_AS_VALUE_SET_NULL (val);
} else if (!SWFDEC_AS_VALUE_IS_NULL (val)) {
SWFDEC_AS_VALUE_SET_STRING (val,
- swfdec_as_value_to_string (context, val));
+ swfdec_abc_value_to_string (context, val));
}
/* else NULL stays the same */
continue;
@@ -739,8 +740,8 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
continue;
case SWFDEC_ABC_OPCODE_DIVIDE:
val = swfdec_as_stack_peek (context, 1);
- SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val)
- / swfdec_as_value_to_number (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_abc_value_to_number (context, val)
+ / swfdec_abc_value_to_number (context, swfdec_as_stack_pop (context)));
continue;
case SWFDEC_ABC_OPCODE_DUP:
val = swfdec_as_stack_peek (context, 1);
@@ -827,7 +828,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
if (!swfdec_abc_interpret_resolve_multiname (context, &mn, &pool->multinames[i]))
break;
object = swfdec_as_stack_pop (context);
- traits = swfdec_as_value_to_traits (context, object);
+ traits = swfdec_abc_value_to_traits (context, object);
/* FIXME: do we capture init vs set right? */
if (fun == traits->construct) {
if (!swfdec_abc_object_init_variable (context, object, &mn, val))
@@ -850,26 +851,26 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_MODULO:
val = swfdec_as_stack_peek (context, 2);
SWFDEC_AS_VALUE_SET_NUMBER (val, fmod (
- swfdec_as_value_to_number (context, val),
- swfdec_as_value_to_number (context, swfdec_as_stack_pop (context))));
+ swfdec_abc_value_to_number (context, val),
+ swfdec_abc_value_to_number (context, swfdec_as_stack_pop (context))));
break;
case SWFDEC_ABC_OPCODE_MULTIPLY:
val = swfdec_as_stack_peek (context, 2);
- SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val) *
- swfdec_as_value_to_number (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_abc_value_to_number (context, val) *
+ swfdec_abc_value_to_number (context, swfdec_as_stack_pop (context)));
break;
case SWFDEC_ABC_OPCODE_MULTIPLY_I:
val = swfdec_as_stack_peek (context, 2);
- SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) *
- swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_abc_value_to_integer (context, val) *
+ swfdec_abc_value_to_integer (context, swfdec_as_stack_pop (context)));
break;
case SWFDEC_ABC_OPCODE_NEGATE:
val = swfdec_as_stack_peek (context, 1);
- SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val));
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_abc_value_to_number (context, val));
break;
case SWFDEC_ABC_OPCODE_NEGATE_I:
val = swfdec_as_stack_peek (context, 1);
- SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val));
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_abc_value_to_integer (context, val));
break;
case SWFDEC_ABC_OPCODE_NEW_CLASS:
{
@@ -880,7 +881,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
if (!swfdec_abc_traits_coerce (SWFDEC_ABC_CLASS_TRAITS (context), val)) {
swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_REFERENCE_ERROR,
"Type Coercion failed: cannot convert %s to %s.",
- swfdec_as_value_get_type_name (val), "Class");
+ swfdec_abc_value_get_type_name (val), "Class");
break;
}
chain = swfdec_abc_scope_chain_new (context, outer_scope,
@@ -960,13 +961,13 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
continue;
case SWFDEC_ABC_OPCODE_SUBTRACT:
val = swfdec_as_stack_peek (context, 2);
- SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val) -
- swfdec_as_value_to_number (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_abc_value_to_number (context, val) -
+ swfdec_abc_value_to_number (context, swfdec_as_stack_pop (context)));
break;
case SWFDEC_ABC_OPCODE_SUBTRACT_I:
val = swfdec_as_stack_peek (context, 2);
- SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) -
- swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_abc_value_to_integer (context, val) -
+ swfdec_abc_value_to_integer (context, swfdec_as_stack_pop (context)));
break;
case SWFDEC_ABC_OPCODE_PUSH_TRUE:
SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_push (context), TRUE);
diff --git a/swfdec/swfdec_abc_object.c b/swfdec/swfdec_abc_object.c
index 9e58519..3216505 100644
--- a/swfdec/swfdec_abc_object.c
+++ b/swfdec/swfdec_abc_object.c
@@ -216,7 +216,7 @@ swfdec_abc_object_get_variable (SwfdecAsContext *context, const SwfdecAsValue *o
g_return_val_if_fail (mn != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
- traits = swfdec_as_value_to_traits (context, object);
+ traits = swfdec_abc_value_to_traits (context, object);
trait = swfdec_abc_traits_find_trait_multi (traits, mn);
if (!trait) {
if (!SWFDEC_AS_VALUE_IS_OBJECT (object) || traits->sealed ||
@@ -285,7 +285,7 @@ swfdec_abc_object_set_variable_full (SwfdecAsContext *context, const SwfdecAsVal
SwfdecAbcTraits *traits;
const SwfdecAbcTrait *trait;
- traits = swfdec_as_value_to_traits (context, object);
+ traits = swfdec_abc_value_to_traits (context, object);
trait = swfdec_abc_traits_find_trait_multi (traits, mn);
if (trait == NULL) {
if (!SWFDEC_AS_VALUE_IS_OBJECT (object) || traits->sealed ||
@@ -389,7 +389,7 @@ swfdec_abc_object_call_variable (SwfdecAsContext *context, const SwfdecAsValue *
"%s is not a function.", mn->name);
return FALSE;
}
- traits = swfdec_as_value_to_traits (context, object);
+ traits = swfdec_abc_value_to_traits (context, object);
trait = swfdec_abc_traits_find_trait_multi (traits, mn);
if (trait == SWFDEC_ABC_TRAIT_AMBIGUOUS) {
swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_REFERENCE_ERROR,
diff --git a/swfdec/swfdec_abc_object.h b/swfdec/swfdec_abc_object.h
index 018a756..70f81fb 100644
--- a/swfdec/swfdec_abc_object.h
+++ b/swfdec/swfdec_abc_object.h
@@ -62,6 +62,10 @@ SwfdecAbcObject * swfdec_abc_object_new (SwfdecAbcTraits * traits,
SwfdecAbcScopeChain * scopes);
SwfdecAbcObject * swfdec_abc_object_new_from_class(SwfdecAbcClass * classp);
+gboolean swfdec_abc_object_default_value (SwfdecAbcObject * object,
+ SwfdecAsValue * default_value);
+gboolean swfdec_abc_object_to_string (SwfdecAbcObject * object,
+ SwfdecAsValue * string);
gboolean swfdec_abc_object_call (SwfdecAbcObject * object,
guint argc,
SwfdecAsValue * argv,
diff --git a/swfdec/swfdec_abc_traits.c b/swfdec/swfdec_abc_traits.c
index 5585108..c924ad6 100644
--- a/swfdec/swfdec_abc_traits.c
+++ b/swfdec/swfdec_abc_traits.c
@@ -32,6 +32,7 @@
#include "swfdec_abc_multiname.h"
#include "swfdec_abc_namespace.h"
#include "swfdec_abc_object.h"
+#include "swfdec_abc_value.h"
#include "swfdec_as_context.h"
#include "swfdec_as_strings.h"
#include "swfdec_debug.h"
@@ -335,7 +336,7 @@ swfdec_abc_traits_is_traits (SwfdecAbcTraits *traits, SwfdecAbcTraits *parent)
}
SwfdecAbcTraits *
-swfdec_as_value_to_traits (SwfdecAsContext *context, const SwfdecAsValue *value)
+swfdec_abc_value_to_traits (SwfdecAsContext *context, const SwfdecAsValue *value)
{
g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
g_return_val_if_fail (value != NULL, NULL);
@@ -371,7 +372,7 @@ swfdec_as_value_to_traits (SwfdecAsContext *context, const SwfdecAsValue *value)
}
gboolean
-swfdec_as_value_is_traits (const SwfdecAsValue *value, SwfdecAbcTraits *traits)
+swfdec_abc_value_is_traits (const SwfdecAsValue *value, SwfdecAbcTraits *traits)
{
SwfdecAsContext *context;
SwfdecAbcTraits *vtraits;
@@ -380,7 +381,7 @@ swfdec_as_value_is_traits (const SwfdecAsValue *value, SwfdecAbcTraits *traits)
g_return_val_if_fail (SWFDEC_IS_ABC_TRAITS (traits), FALSE);
context = swfdec_gc_object_get_context (traits);
- vtraits = swfdec_as_value_to_traits (context, value);
+ vtraits = swfdec_abc_value_to_traits (context, value);
return swfdec_abc_traits_is_traits (vtraits, traits);
}
@@ -396,30 +397,30 @@ swfdec_abc_traits_coerce (SwfdecAbcTraits *traits, SwfdecAsValue *val)
if (traits == SWFDEC_ABC_BOOLEAN_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_BOOLEAN (val,
- swfdec_as_value_to_boolean (context, val));
+ swfdec_abc_value_to_boolean (context, val));
return TRUE;
} else if (traits == SWFDEC_ABC_NUMBER_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
- swfdec_as_value_to_number (context, val));
+ swfdec_abc_value_to_number (context, val));
return TRUE;
} else if (traits == SWFDEC_ABC_INT_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_INT (val,
- swfdec_as_value_to_integer (context, val));
+ swfdec_abc_value_to_integer (context, val));
return TRUE;
} else if (traits == SWFDEC_ABC_UINT_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
- (guint) swfdec_as_value_to_integer (context, val));
+ (guint) swfdec_abc_value_to_integer (context, val));
return TRUE;
} else if (traits == SWFDEC_ABC_NUMBER_TRAITS (context)) {
SWFDEC_AS_VALUE_SET_NUMBER (val,
- (guint) swfdec_as_value_to_integer (context, val));
+ (guint) swfdec_abc_value_to_integer (context, val));
return TRUE;
} else if (traits == SWFDEC_ABC_STRING_TRAITS (context)) {
if (SWFDEC_AS_VALUE_IS_UNDEFINED (val) || SWFDEC_AS_VALUE_IS_NULL (val)) {
SWFDEC_AS_VALUE_SET_NULL (val);
} else {
SWFDEC_AS_VALUE_SET_STRING (val,
- swfdec_as_value_to_string (context, val));
+ swfdec_abc_value_to_string (context, val));
}
return TRUE;
} else if (traits == SWFDEC_ABC_OBJECT_TRAITS (context)) {
@@ -438,6 +439,6 @@ swfdec_abc_traits_coerce (SwfdecAbcTraits *traits, SwfdecAsValue *val)
return TRUE;
}
- return swfdec_as_value_is_traits (val, traits);
+ return swfdec_abc_value_is_traits (val, traits);
}
diff --git a/swfdec/swfdec_abc_traits.h b/swfdec/swfdec_abc_traits.h
index a1a09a1..b69a6b4 100644
--- a/swfdec/swfdec_abc_traits.h
+++ b/swfdec/swfdec_abc_traits.h
@@ -140,9 +140,9 @@ gboolean swfdec_abc_traits_is_traits (SwfdecAbcTraits * traits,
gboolean swfdec_abc_traits_coerce (SwfdecAbcTraits * traits,
SwfdecAsValue * val);
/* FIXME: kinda wrong header */
-SwfdecAbcTraits * swfdec_as_value_to_traits (SwfdecAsContext * context,
+SwfdecAbcTraits * swfdec_abc_value_to_traits (SwfdecAsContext * context,
const SwfdecAsValue * value);
-gboolean swfdec_as_value_is_traits (const SwfdecAsValue * value,
+gboolean swfdec_abc_value_is_traits (const SwfdecAsValue * value,
SwfdecAbcTraits * traits);
diff --git a/swfdec/swfdec_abc_value.c b/swfdec/swfdec_abc_value.c
new file mode 100644
index 0000000..dc58fc6
--- /dev/null
+++ b/swfdec/swfdec_abc_value.c
@@ -0,0 +1,240 @@
+/* Swfdec
+ * Copyright (C) 2008 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_abc_value.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "swfdec_abc_namespace.h"
+#include "swfdec_abc_object.h"
+#include "swfdec_abc_traits.h"
+#include "swfdec_as_context.h"
+#include "swfdec_as_strings.h"
+#include "swfdec_debug.h"
+
+gboolean
+swfdec_abc_value_to_boolean (SwfdecAsContext *context, const SwfdecAsValue *value)
+{
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), FALSE);
+
+ switch (SWFDEC_AS_VALUE_GET_TYPE (value)) {
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ case SWFDEC_AS_TYPE_NULL:
+ return FALSE;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_VALUE_GET_BOOLEAN (value);
+ case SWFDEC_AS_TYPE_NUMBER:
+ {
+ double d = SWFDEC_AS_VALUE_GET_NUMBER (value);
+ return !isnan (d) && d != 0.0;
+ }
+ case SWFDEC_AS_TYPE_STRING:
+ return SWFDEC_AS_VALUE_GET_STRING (value) != SWFDEC_AS_STR_EMPTY;
+ case SWFDEC_AS_TYPE_OBJECT:
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return TRUE;
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
+int
+swfdec_abc_value_to_integer (SwfdecAsContext *context, const SwfdecAsValue *value)
+{
+ double d;
+
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0);
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), 0);
+
+ d = swfdec_abc_value_to_number (context, value);
+
+ if (!isfinite (d))
+ return 0;
+ if (d < 0) {
+ d = fmod (-d, 4294967296.0);
+ return - (guint) d;
+ } else {
+ d = fmod (d, 4294967296.0);
+ return (guint) d;
+ }
+}
+
+double
+swfdec_abc_value_to_number (SwfdecAsContext *context, const SwfdecAsValue *value)
+{
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0.0);
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), 0.0);
+
+ switch (SWFDEC_AS_VALUE_GET_TYPE (value)) {
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ case SWFDEC_AS_TYPE_NULL:
+ return NAN;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_VALUE_GET_BOOLEAN (value) ? 1.0 : 0.0;
+ case SWFDEC_AS_TYPE_NUMBER:
+ return SWFDEC_AS_VALUE_GET_NUMBER (value);
+ case SWFDEC_AS_TYPE_STRING:
+ return swfdec_as_string_to_number (context, SWFDEC_AS_VALUE_GET_STRING (value));
+ case SWFDEC_AS_TYPE_OBJECT:
+ {
+ SwfdecAsValue tmp;
+ if (!swfdec_abc_object_default_value (
+ SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (value)), &tmp))
+ return NAN;
+ return swfdec_abc_value_to_number (context, &tmp);
+ }
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return swfdec_as_string_to_number (context, SWFDEC_AS_VALUE_GET_NAMESPACE (value)->uri);
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
+gboolean
+swfdec_abc_value_to_primitive (SwfdecAsValue *dest, const SwfdecAsValue *src)
+{
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (dest), FALSE);
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (src), FALSE);
+
+ if (SWFDEC_AS_VALUE_IS_OBJECT (src)) {
+ return swfdec_abc_object_default_value
+ (SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (src)), dest);
+ } else if (dest != src) {
+ *dest = *src;
+ }
+ return TRUE;
+}
+
+const char *
+swfdec_abc_value_to_string (SwfdecAsContext *context, const SwfdecAsValue *value)
+{
+ 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);
+
+ switch (SWFDEC_AS_VALUE_GET_TYPE (value)) {
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ return SWFDEC_AS_STR_undefined;
+ case SWFDEC_AS_TYPE_NULL:
+ return SWFDEC_AS_STR_null;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_VALUE_GET_BOOLEAN (value) ? SWFDEC_AS_STR_true : SWFDEC_AS_STR_false;
+ case SWFDEC_AS_TYPE_NUMBER:
+ return swfdec_as_double_to_string (context, SWFDEC_AS_VALUE_GET_NUMBER (value));
+ case SWFDEC_AS_TYPE_STRING:
+ return SWFDEC_AS_VALUE_GET_STRING (value);
+ case SWFDEC_AS_TYPE_OBJECT:
+ {
+ SwfdecAsValue tmp;
+ if (!swfdec_abc_object_to_string (
+ SWFDEC_ABC_OBJECT (SWFDEC_AS_VALUE_GET_OBJECT (value)), &tmp))
+ return SWFDEC_AS_STR_EMPTY;
+ return swfdec_abc_value_to_string (context, &tmp);
+ }
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return SWFDEC_AS_VALUE_GET_NAMESPACE (value)->uri;
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
+const char *
+swfdec_abc_value_get_type_name (const SwfdecAsValue *value)
+{
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), NULL);
+
+ switch (value->type) {
+ case SWFDEC_AS_TYPE_STRING:
+ return SWFDEC_AS_STR_String;
+ case SWFDEC_AS_TYPE_UNDEFINED:
+ return SWFDEC_AS_STR_void;
+ case SWFDEC_AS_TYPE_BOOLEAN:
+ return SWFDEC_AS_STR_Boolean;
+ case SWFDEC_AS_TYPE_NULL:
+ return SWFDEC_AS_STR_null;
+ case SWFDEC_AS_TYPE_NUMBER:
+ return SWFDEC_AS_STR_Number;
+ case SWFDEC_AS_TYPE_OBJECT:
+ {
+ SwfdecAsObject *object = SWFDEC_AS_VALUE_GET_OBJECT (value);
+ if (SWFDEC_IS_ABC_OBJECT (object))
+ return SWFDEC_ABC_OBJECT (object)->traits->name;
+ return SWFDEC_AS_STR_Object;
+ }
+ case SWFDEC_AS_TYPE_NAMESPACE:
+ return SWFDEC_AS_STR_Namespace;
+ case SWFDEC_AS_TYPE_INT:
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+/**
+ * swfdec_abc_value_compare:
+ * @context: the context the values beliong to
+ * @lval: the left-side value of the comparison
+ * @rval: the right-side value of the comparison
+ *
+ * Does the ABC lower-or-equal comparison, as in @lval <= @rval. Be aware that
+ * this function can throw an exception.
+ *
+ * Returns: see #SwfdecAbcComparison
+ **/
+SwfdecAbcComparison
+swfdec_abc_value_compare (SwfdecAsContext *context, const SwfdecAsValue *lval,
+ const SwfdecAsValue *rval)
+{
+ SwfdecAsValue ltmp, rtmp;
+
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (lval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+ g_return_val_if_fail (rval != NULL, SWFDEC_ABC_COMPARE_UNDEFINED);
+
+ if (!swfdec_abc_value_to_primitive (<mp, lval) ||
+ !swfdec_abc_value_to_primitive (&rtmp, rval))
+ return SWFDEC_ABC_COMPARE_THROWN;
+
+ if (SWFDEC_AS_VALUE_IS_STRING (<mp) && SWFDEC_AS_VALUE_IS_STRING (&rtmp)) {
+ int comp = strcmp (SWFDEC_AS_VALUE_GET_STRING (<mp),
+ SWFDEC_AS_VALUE_GET_STRING (&rtmp));
+ return (comp < 0) ? SWFDEC_ABC_COMPARE_LOWER :
+ (comp > 0 ? SWFDEC_ABC_COMPARE_GREATER : SWFDEC_ABC_COMPARE_EQUAL);
+ } else {
+ double l = swfdec_as_value_to_number (context, <mp);
+ double r = swfdec_as_value_to_number (context, &rtmp);
+ if (isnan (l) || isnan (r))
+ return SWFDEC_ABC_COMPARE_UNDEFINED;
+
+ return (l < r) ? SWFDEC_ABC_COMPARE_LOWER :
+ (l > r ? SWFDEC_ABC_COMPARE_GREATER : SWFDEC_ABC_COMPARE_EQUAL);
+ }
+}
+
diff --git a/swfdec/swfdec_abc_value.h b/swfdec/swfdec_abc_value.h
new file mode 100644
index 0000000..dfccd87
--- /dev/null
+++ b/swfdec/swfdec_abc_value.h
@@ -0,0 +1,57 @@
+/* Swfdec
+ * Copyright (C) 2008 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_ABC_VALUE_H_
+#define _SWFDEC_ABC_VALUE_H_
+
+#include <swfdec/swfdec_abc_types.h>
+#include <swfdec/swfdec_as_types.h>
+
+G_BEGIN_DECLS
+
+
+typedef enum {
+ SWFDEC_ABC_COMPARE_UNDEFINED,
+ SWFDEC_ABC_COMPARE_THROWN,
+ SWFDEC_ABC_COMPARE_LOWER,
+ SWFDEC_ABC_COMPARE_EQUAL,
+ SWFDEC_ABC_COMPARE_GREATER
+} SwfdecAbcComparison;
+
+gboolean swfdec_abc_value_to_boolean (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+int swfdec_abc_value_to_integer (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+double swfdec_abc_value_to_number (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+SwfdecAsObject * swfdec_abc_value_to_object (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+gboolean swfdec_abc_value_to_primitive (SwfdecAsValue * dest,
+ const SwfdecAsValue * src);
+const char * swfdec_abc_value_to_string (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+const char * swfdec_abc_value_get_type_name (const SwfdecAsValue * value);
+
+SwfdecAbcComparison swfdec_abc_value_compare (SwfdecAsContext * context,
+ const SwfdecAsValue * lval,
+ const SwfdecAsValue * rval);
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec/swfdec_as_types.c b/swfdec/swfdec_as_types.c
index 2ca4a5f..92850a3 100644
--- a/swfdec/swfdec_as_types.c
+++ b/swfdec/swfdec_as_types.c
@@ -458,39 +458,7 @@ swfdec_as_value_to_debug (const SwfdecAsValue *value)
}
}
-const char *
-swfdec_as_value_get_type_name (const SwfdecAsValue *value)
-{
- g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), NULL);
-
- switch (value->type) {
- case SWFDEC_AS_TYPE_STRING:
- return SWFDEC_AS_STR_String;
- case SWFDEC_AS_TYPE_UNDEFINED:
- return SWFDEC_AS_STR_void;
- case SWFDEC_AS_TYPE_BOOLEAN:
- return SWFDEC_AS_STR_Boolean;
- case SWFDEC_AS_TYPE_NULL:
- return SWFDEC_AS_STR_null;
- case SWFDEC_AS_TYPE_NUMBER:
- return SWFDEC_AS_STR_Number;
- case SWFDEC_AS_TYPE_OBJECT:
- {
- SwfdecAsObject *object = SWFDEC_AS_VALUE_GET_OBJECT (value);
- if (SWFDEC_IS_ABC_OBJECT (object))
- return SWFDEC_ABC_OBJECT (object)->traits->name;
- return SWFDEC_AS_STR_Object;
- }
- case SWFDEC_AS_TYPE_NAMESPACE:
- return SWFDEC_AS_STR_Namespace;
- case SWFDEC_AS_TYPE_INT:
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-static double
+double
swfdec_as_string_to_number (SwfdecAsContext *context, const char *s)
{
char *end;
diff --git a/swfdec/swfdec_as_types.h b/swfdec/swfdec_as_types.h
index f291ddd..54f7324 100644
--- a/swfdec/swfdec_as_types.h
+++ b/swfdec/swfdec_as_types.h
@@ -69,7 +69,8 @@ struct _SwfdecAsValue {
} value;
};
-#define SWFDEC_IS_AS_VALUE(val) ((val) != NULL && (val)->type <= SWFDEC_TYPE_ABC_NAMESPACE)
+#define SWFDEC_AS_VALUE_GET_TYPE(val) ((val)->type)
+#define SWFDEC_IS_AS_VALUE(val) ((val) != NULL && SWFDEC_AS_VALUE_GET_TYPE (val) <= SWFDEC_AS_TYPE_NAMESPACE)
#define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_AS_TYPE_UNDEFINED)
#define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_AS_TYPE_UNDEFINED
@@ -139,7 +140,6 @@ SwfdecAsObject *swfdec_as_value_to_object (SwfdecAsContext * context,
void swfdec_as_value_to_primitive (SwfdecAsValue * value);
const char * swfdec_as_value_to_string (SwfdecAsContext * context,
const SwfdecAsValue * value);
-const char * swfdec_as_value_get_type_name (const SwfdecAsValue * value);
char * swfdec_as_value_to_debug (const SwfdecAsValue * value);
/* special conversion functions */
@@ -148,6 +148,8 @@ const char * swfdec_as_integer_to_string (SwfdecAsContext * context,
int swfdec_as_double_to_integer (double d);
const char * swfdec_as_double_to_string (SwfdecAsContext * context,
double d);
+double swfdec_as_string_to_number (SwfdecAsContext * context,
+ const char * s);
const char * swfdec_as_str_concat (SwfdecAsContext * cx,
const char * s1,
const char * s2);
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 7a2b5b8..2ced46a 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -549,7 +549,7 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
swfdec_sandbox_use (sandbox);
swfdec_abc_multiname_init_from_string (&mn, context, s);
swfdec_as_context_get_abc_variable (context, &mn, &val);
- if (swfdec_as_value_is_traits (&val, SWFDEC_ABC_CLASS_TRAITS (context))) {
+ if (swfdec_abc_value_is_traits (&val, SWFDEC_ABC_CLASS_TRAITS (context))) {
swfdec_resource_add_abc_class (mov->resource, id,
SWFDEC_ABC_CLASS (SWFDEC_AS_VALUE_GET_OBJECT (&val)));
} else {
commit c80e955af5fa8e57b56f8c76fb8e24bdbf35f9e2
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Aug 23 18:51:42 2008 +0200
implement add_i, modulo, multiply(_i), negate(_i) and subtract(_i) opcodes
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index 7224c1d..7413056 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -658,6 +658,11 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
}
}
continue;
+ case SWFDEC_ABC_OPCODE_ADD_I:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) +
+ swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ break;
case SWFDEC_ABC_OPCODE_CALL_PROPERTY:
case SWFDEC_ABC_OPCODE_CALL_PROP_LEX:
case SWFDEC_ABC_OPCODE_CALL_PROP_VOID:
@@ -842,6 +847,30 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
i = swfdec_bits_get_vu32 (&bits);
SWFDEC_AS_VALUE_SET_UNDEFINED (&locals[i]);
continue;
+ case SWFDEC_ABC_OPCODE_MODULO:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, fmod (
+ swfdec_as_value_to_number (context, val),
+ swfdec_as_value_to_number (context, swfdec_as_stack_pop (context))));
+ break;
+ case SWFDEC_ABC_OPCODE_MULTIPLY:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val) *
+ swfdec_as_value_to_number (context, swfdec_as_stack_pop (context)));
+ break;
+ case SWFDEC_ABC_OPCODE_MULTIPLY_I:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) *
+ swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ break;
+ case SWFDEC_ABC_OPCODE_NEGATE:
+ val = swfdec_as_stack_peek (context, 1);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val));
+ break;
+ case SWFDEC_ABC_OPCODE_NEGATE_I:
+ val = swfdec_as_stack_peek (context, 1);
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val));
+ break;
case SWFDEC_ABC_OPCODE_NEW_CLASS:
{
SwfdecAbcClass *classp;
@@ -929,6 +958,16 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
i = swfdec_bits_get_vu32 (&bits);
SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (context), pool->strings[i]);
continue;
+ case SWFDEC_ABC_OPCODE_SUBTRACT:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val) -
+ swfdec_as_value_to_number (context, swfdec_as_stack_pop (context)));
+ break;
+ case SWFDEC_ABC_OPCODE_SUBTRACT_I:
+ val = swfdec_as_stack_peek (context, 2);
+ SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (context, val) -
+ swfdec_as_value_to_integer (context, swfdec_as_stack_pop (context)));
+ break;
case SWFDEC_ABC_OPCODE_PUSH_TRUE:
SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_push (context), TRUE);
continue;
@@ -985,7 +1024,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
continue;
case SWFDEC_ABC_OPCODE_ABS_JUMP:
case SWFDEC_ABC_OPCODE_ADD_D:
- case SWFDEC_ABC_OPCODE_ADD_I:
case SWFDEC_ABC_OPCODE_ALLOC:
case SWFDEC_ABC_OPCODE_AS_TYPE:
case SWFDEC_ABC_OPCODE_AS_TYPE_LATE:
@@ -1065,11 +1103,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_LOOKUP_SWITCH:
case SWFDEC_ABC_OPCODE_LSHIFT:
case SWFDEC_ABC_OPCODE_MARK:
- case SWFDEC_ABC_OPCODE_MODULO:
- case SWFDEC_ABC_OPCODE_MULTIPLY:
- case SWFDEC_ABC_OPCODE_MULTIPLY_I:
- case SWFDEC_ABC_OPCODE_NEGATE:
- case SWFDEC_ABC_OPCODE_NEGATE_I:
case SWFDEC_ABC_OPCODE_NEXT_NAME:
case SWFDEC_ABC_OPCODE_NEXT_VALUE:
case SWFDEC_ABC_OPCODE_NEW_ARRAY:
@@ -1086,8 +1119,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_SET_SLOT:
case SWFDEC_ABC_OPCODE_SET_SUPER:
case SWFDEC_ABC_OPCODE_STRICT_EQUALS:
- case SWFDEC_ABC_OPCODE_SUBTRACT:
- case SWFDEC_ABC_OPCODE_SUBTRACT_I:
case SWFDEC_ABC_OPCODE_SWEEP:
case SWFDEC_ABC_OPCODE_THROW:
case SWFDEC_ABC_OPCODE_TIMESTAMP:
commit 52555c8820cbd4363e8bb4cc079152fa52114e4c
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Aug 23 18:12:48 2008 +0200
implement debug, debugfile and debugline opcodes (by ignoring them)
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index a363488..7224c1d 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -722,6 +722,16 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
outer_scope ? outer_scope->base : NULL, i, val, val);
swfdec_as_stack_pop_n (context, i + 1);
continue;
+ case SWFDEC_ABC_OPCODE_DEBUG:
+ /* type = */ swfdec_bits_get_u8 (&bits);
+ /* name = */ swfdec_bits_get_vu32 (&bits);
+ /* register = */ swfdec_bits_get_u8 (&bits);
+ /* extra = */ swfdec_bits_get_vu32 (&bits);
+ break;
+ case SWFDEC_ABC_OPCODE_DEBUG_FILE:
+ case SWFDEC_ABC_OPCODE_DEBUG_LINE:
+ i = swfdec_bits_get_vu32 (&bits);
+ continue;
case SWFDEC_ABC_OPCODE_DIVIDE:
val = swfdec_as_stack_peek (context, 1);
SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (context, val)
@@ -1007,9 +1017,6 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
case SWFDEC_ABC_OPCODE_CONVERT_O:
case SWFDEC_ABC_OPCODE_CONVERT_S:
case SWFDEC_ABC_OPCODE_CONVERT_U:
- case SWFDEC_ABC_OPCODE_DEBUG:
- case SWFDEC_ABC_OPCODE_DEBUG_FILE:
- case SWFDEC_ABC_OPCODE_DEBUG_LINE:
case SWFDEC_ABC_OPCODE_DEC_LOCAL:
case SWFDEC_ABC_OPCODE_DECLOCAL_I:
case SWFDEC_ABC_OPCODE_DECODE:
More information about the Swfdec-commits
mailing list