diff options
author | Benjamin Otte <otte@gnome.org> | 2008-08-26 18:12:54 +0200 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2008-08-26 18:12:54 +0200 |
commit | 658f96fc119f9adbb07d81a57e6a82d9e8c24b50 (patch) | |
tree | c9ca42312007859e6bba551ee86a86bd530e2ea5 | |
parent | 0976cee9297b4da790bd4bdafa294513295f3858 (diff) |
implement construct and constructprop opcodesabc
-rw-r--r-- | swfdec/swfdec_abc_interpret.c | 36 | ||||
-rw-r--r-- | swfdec/swfdec_abc_object.c | 19 | ||||
-rw-r--r-- | swfdec/swfdec_abc_object.h | 7 |
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 |