summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2008-08-26 18:12:54 +0200
committerBenjamin Otte <otte@gnome.org>2008-08-26 18:12:54 +0200
commit658f96fc119f9adbb07d81a57e6a82d9e8c24b50 (patch)
treec9ca42312007859e6bba551ee86a86bd530e2ea5
parent0976cee9297b4da790bd4bdafa294513295f3858 (diff)
implement construct and constructprop opcodesabc
-rw-r--r--swfdec/swfdec_abc_interpret.c36
-rw-r--r--swfdec/swfdec_abc_object.c19
-rw-r--r--swfdec/swfdec_abc_object.h7
3 files changed, 57 insertions, 5 deletions
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index 59ca074c..bb647895 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 5147fd8d..d0597b33 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 06395c48..683276d3 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