[Swfdec-commits] 7 commits - swfdec/swfdec_movie.c swfdec/swfdec_movie.h swfdec/swfdec_resource.c swfdec/swfdec_sprite_movie_as.c test/trace vivified/code

Pekka Lampila medar at kemper.freedesktop.org
Sun Apr 13 06:04:24 PDT 2008


 swfdec/swfdec_movie.c                               |   11 +
 swfdec/swfdec_movie.h                               |    1 
 swfdec/swfdec_resource.c                            |    1 
 swfdec/swfdec_sprite_movie_as.c                     |   13 +
 test/trace/Makefile.am                              |   16 +
 test/trace/movieclip-lockroot-5.swf                 |binary
 test/trace/movieclip-lockroot-5.swf.trace           |    3 
 test/trace/movieclip-lockroot-6.swf                 |binary
 test/trace/movieclip-lockroot-6.swf.trace           |    3 
 test/trace/movieclip-lockroot-7.swf                 |binary
 test/trace/movieclip-lockroot-7.swf.trace           |    3 
 test/trace/movieclip-lockroot-8.swf                 |binary
 test/trace/movieclip-lockroot-8.swf.trace           |    3 
 test/trace/movieclip-lockroot-loadmovie-6.swf       |binary
 test/trace/movieclip-lockroot-loadmovie-6.swf.trace |   39 ++++
 test/trace/movieclip-lockroot-loadmovie-7.swf       |binary
 test/trace/movieclip-lockroot-loadmovie-7.swf.trace |   39 ++++
 test/trace/movieclip-lockroot-loadmovie-8.swf       |binary
 test/trace/movieclip-lockroot-loadmovie-8.swf.trace |   39 ++++
 test/trace/movieclip-lockroot-loadmovie.as          |   20 ++
 test/trace/movieclip-lockroot.as                    |   15 +
 vivified/code/Makefile.am                           |    4 
 vivified/code/vivi_code_constant.h                  |    1 
 vivified/code/vivi_code_play.c                      |   46 +++++
 vivified/code/vivi_code_play.h                      |   55 ++++++
 vivified/code/vivi_code_special_statement.c         |   81 +++++++++
 vivified/code/vivi_code_special_statement.h         |   60 ++++++
 vivified/code/vivi_code_trace.c                     |   35 +--
 vivified/code/vivi_code_trace.h                     |    5 
 vivified/code/vivi_parser.c                         |  178 ++++++++++++++++----
 vivified/code/vivi_parser_scanner.c                 |    1 
 vivified/code/vivi_parser_scanner.h                 |    1 
 vivified/code/vivi_parser_scanner_lex.l             |    1 
 33 files changed, 614 insertions(+), 60 deletions(-)

New commits:
commit a838e42b2618038fe5d03aad4bf58995c99f32f9
Merge: 16a524e... 1432a6b...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Apr 13 15:54:54 2008 +0300

    Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec

commit 16a524ede68833e05e8b283c00e5127e913513c7
Merge: 8193443... 90341d8...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Apr 13 15:54:31 2008 +0300

    Merge branch 'lockroot'

commit 81934434ea7e0404883400916ecdd951807b7b27
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Apr 13 15:53:58 2008 +0300

    Create a mechanism for handling special statements when compiling
    
    Currently only trace and play are handled

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index d0f9c0a..789bae3 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -34,8 +34,10 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_init_object.c \
 	vivi_code_label.c \
 	vivi_code_loop.c \
+	vivi_code_play.c \
 	vivi_code_printer.c \
 	vivi_code_return.c \
+	vivi_code_special_statement.c \
 	vivi_code_statement.c \
 	vivi_code_text_printer.c \
 	vivi_code_throw.c \
@@ -74,8 +76,10 @@ noinst_HEADERS = \
 	vivi_code_init_object.h \
 	vivi_code_label.h \
 	vivi_code_loop.h \
+	vivi_code_play.h \
 	vivi_code_printer.h \
 	vivi_code_return.h \
+	vivi_code_special_statement.h \
 	vivi_code_statement.h \
 	vivi_code_text_printer.h \
 	vivi_code_throw.h \
diff --git a/vivified/code/vivi_code_constant.h b/vivified/code/vivi_code_constant.h
index 714bcc2..bf46a4b 100644
--- a/vivified/code/vivi_code_constant.h
+++ b/vivified/code/vivi_code_constant.h
@@ -61,6 +61,7 @@ char *			vivi_code_constant_get_variable_name
 SwfdecAsValueType	vivi_code_constant_get_value_type
 							(ViviCodeConstant *	constant);
 double			vivi_code_constant_get_number	(ViviCodeConstant *	constant);
+const char *		vivi_code_constant_get_string	(ViviCodeConstant *	constant);
 
 G_END_DECLS
 #endif
diff --git a/vivified/code/vivi_code_play.c b/vivified/code/vivi_code_play.c
new file mode 100644
index 0000000..4b3f3cf
--- /dev/null
+++ b/vivified/code/vivi_code_play.c
@@ -0,0 +1,46 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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 "vivi_code_play.h"
+
+G_DEFINE_TYPE (ViviCodePlay, vivi_code_play, VIVI_TYPE_CODE_SPECIAL_STATEMENT)
+
+static void
+vivi_code_play_class_init (ViviCodePlayClass *klass)
+{
+}
+
+static void
+vivi_code_play_init (ViviCodePlay *token)
+{
+  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+
+  stmt->name = "play";
+  stmt->action = SWFDEC_AS_ACTION_PLAY;
+}
+
+ViviCodeStatement *
+vivi_code_play_new (void)
+{
+  return g_object_new (VIVI_TYPE_CODE_PLAY, NULL);
+}
diff --git a/vivified/code/vivi_code_play.h b/vivified/code/vivi_code_play.h
new file mode 100644
index 0000000..371dd57
--- /dev/null
+++ b/vivified/code/vivi_code_play.h
@@ -0,0 +1,55 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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 _VIVI_CODE_PLAY_H_
+#define _VIVI_CODE_PLAY_H_
+
+#include <vivified/code/vivi_code_special_statement.h>
+#include <vivified/code/vivi_code_statement.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodePlay ViviCodePlay;
+typedef struct _ViviCodePlayClass ViviCodePlayClass;
+
+#define VIVI_TYPE_CODE_PLAY                    (vivi_code_play_get_type())
+#define VIVI_IS_CODE_PLAY(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_PLAY))
+#define VIVI_IS_CODE_PLAY_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_PLAY))
+#define VIVI_CODE_PLAY(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_PLAY, ViviCodePlay))
+#define VIVI_CODE_PLAY_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_PLAY, ViviCodePlayClass))
+#define VIVI_CODE_PLAY_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_PLAY, ViviCodePlayClass))
+
+struct _ViviCodePlay
+{
+  ViviCodeSpecialStatement	statement;
+};
+
+struct _ViviCodePlayClass
+{
+  ViviCodeSpecialStatementClass	statement_class;
+};
+
+GType			vivi_code_play_get_type   	(void);
+
+ViviCodeStatement *	vivi_code_play_new		(void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_special_statement.c b/vivified/code/vivi_code_special_statement.c
new file mode 100644
index 0000000..e0b5e07
--- /dev/null
+++ b/vivified/code/vivi_code_special_statement.c
@@ -0,0 +1,81 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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 <string.h>
+
+#include "vivi_code_special_statement.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_ABSTRACT_TYPE (ViviCodeSpecialStatement, vivi_code_special_statement, VIVI_TYPE_CODE_STATEMENT)
+
+static void
+vivi_code_special_statement_print (ViviCodeToken *token,
+    ViviCodePrinter *printer)
+{
+  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+  ViviCodeSpecialStatementClass *klass =
+    VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS (stmt);
+
+  g_assert (stmt->name != NULL);
+  vivi_code_printer_print (printer, stmt->name);
+
+  vivi_code_printer_print (printer, " (");
+
+  if (klass->get_value != NULL) {
+    vivi_code_printer_print_value (printer, klass->get_value (stmt),
+	VIVI_PRECEDENCE_COMMA);
+  }
+
+  vivi_code_printer_print (printer, ");");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_special_statement_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+  ViviCodeSpecialStatementClass *klass =
+    VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS (stmt);
+
+  if (klass->get_value != NULL)
+    vivi_code_compiler_compile_value (compiler, klass->get_value (stmt));
+
+  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, stmt->action);
+}
+
+static void
+vivi_code_special_statement_class_init (ViviCodeSpecialStatementClass *klass)
+{
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  token_class->print = vivi_code_special_statement_print;
+  token_class->compile = vivi_code_special_statement_compile;
+}
+
+static void
+vivi_code_special_statement_init (ViviCodeSpecialStatement *stmt)
+{
+}
diff --git a/vivified/code/vivi_code_special_statement.h b/vivified/code/vivi_code_special_statement.h
new file mode 100644
index 0000000..735c5dd
--- /dev/null
+++ b/vivified/code/vivi_code_special_statement.h
@@ -0,0 +1,60 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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 _VIVI_CODE_SPECIAL_STATEMENT_H_
+#define _VIVI_CODE_SPECIAL_STATEMENT_H_
+
+#include <swfdec/swfdec_as_interpret.h>
+
+#include <vivified/code/vivi_code_statement.h>
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeSpecialStatement ViviCodeSpecialStatement;
+typedef struct _ViviCodeSpecialStatementClass ViviCodeSpecialStatementClass;
+
+#define VIVI_TYPE_CODE_SPECIAL_STATEMENT                    (vivi_code_special_statement_get_type())
+#define VIVI_IS_CODE_SPECIAL_STATEMENT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT))
+#define VIVI_IS_CODE_SPECIAL_STATEMENT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_SPECIAL_STATEMENT))
+#define VIVI_CODE_SPECIAL_STATEMENT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatement))
+#define VIVI_CODE_SPECIAL_STATEMENT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatementClass))
+#define VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatementClass))
+
+struct _ViviCodeSpecialStatement
+{
+  ViviCodeStatement	statement;
+
+  const char		*name;		// can be NULL, if get_name is not
+  SwfdecAsAction	action;
+};
+
+struct _ViviCodeSpecialStatementClass
+{
+  ViviCodeStatementClass	statement_class;
+
+  ViviCodeValue *	(* get_value)			(ViviCodeSpecialStatement *	stmt);
+};
+
+GType		vivi_code_special_statement_get_type		(void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_trace.c b/vivified/code/vivi_code_trace.c
index b8ced24..5fef0ce 100644
--- a/vivified/code/vivi_code_trace.c
+++ b/vivified/code/vivi_code_trace.c
@@ -22,10 +22,8 @@
 #endif
 
 #include "vivi_code_trace.h"
-#include "vivi_code_printer.h"
-#include "vivi_code_compiler.h"
 
-G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_STATEMENT)
+G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_SPECIAL_STATEMENT)
 
 static void
 vivi_code_trace_dispose (GObject *object)
@@ -37,42 +35,33 @@ vivi_code_trace_dispose (GObject *object)
   G_OBJECT_CLASS (vivi_code_trace_parent_class)->dispose (object);
 }
 
-static void
-vivi_code_trace_print (ViviCodeToken *token, ViviCodePrinter *printer)
-{
-  ViviCodeTrace *trace = VIVI_CODE_TRACE (token);
-
-  vivi_code_printer_print (printer, "trace (");
-  vivi_code_printer_print_token (printer, VIVI_CODE_TOKEN (trace->value));
-  vivi_code_printer_print (printer, ");");
-  vivi_code_printer_new_line (printer, FALSE);
-}
-
-static void
-vivi_code_trace_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+static ViviCodeValue *
+vivi_code_trace_get_value (ViviCodeSpecialStatement *stmt)
 {
-  ViviCodeTrace *trace = VIVI_CODE_TRACE (token);
+  ViviCodeTrace *trace = VIVI_CODE_TRACE (stmt);
 
-  vivi_code_compiler_compile_value (compiler, trace->value);
-
-  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_TRACE);
+  return trace->value;
 }
 
 static void
 vivi_code_trace_class_init (ViviCodeTraceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+  ViviCodeSpecialStatementClass *stmt_class =
+    VIVI_CODE_SPECIAL_STATEMENT_CLASS (klass);
 
   object_class->dispose = vivi_code_trace_dispose;
 
-  token_class->print = vivi_code_trace_print;
-  token_class->compile = vivi_code_trace_compile;
+  stmt_class->get_value = vivi_code_trace_get_value;
 }
 
 static void
 vivi_code_trace_init (ViviCodeTrace *token)
 {
+  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+
+  stmt->name = "trace";
+  stmt->action = SWFDEC_AS_ACTION_TRACE;
 }
 
 ViviCodeStatement *
diff --git a/vivified/code/vivi_code_trace.h b/vivified/code/vivi_code_trace.h
index 0591f14..100aa4f 100644
--- a/vivified/code/vivi_code_trace.h
+++ b/vivified/code/vivi_code_trace.h
@@ -20,6 +20,7 @@
 #ifndef _VIVI_CODE_TRACE_H_
 #define _VIVI_CODE_TRACE_H_
 
+#include <vivified/code/vivi_code_special_statement.h>
 #include <vivified/code/vivi_code_statement.h>
 #include <vivified/code/vivi_code_value.h>
 
@@ -38,14 +39,14 @@ typedef struct _ViviCodeTraceClass ViviCodeTraceClass;
 
 struct _ViviCodeTrace
 {
-  ViviCodeStatement	statement;
+  ViviCodeSpecialStatement	statement;
 
   ViviCodeValue *	value;
 };
 
 struct _ViviCodeTraceClass
 {
-  ViviCodeStatementClass	statement_class;
+  ViviCodeSpecialStatementClass	statement_class;
 };
 
 GType			vivi_code_trace_get_type   	(void);
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 12c90a1..ac3e4e3 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -42,6 +42,7 @@
 #include "vivi_code_init_array.h"
 #include "vivi_code_init_object.h"
 #include "vivi_code_loop.h"
+#include "vivi_code_play.h"
 #include "vivi_code_return.h"
 #include "vivi_code_throw.h"
 #include "vivi_code_trace.h"
@@ -906,6 +907,153 @@ parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
   *statement = vivi_parser_join_statements (statement_right, assignment);
 }
 
+// special functions
+
+typedef void (*ParseArgumentFunction) (ParseData *data, guint position,
+    ViviCodeValue **value, ViviCodeStatement **statement);
+
+/*static void
+parse_url_method (ParseData *data, ViviCodeValue **value)
+{
+  if (peek_identifier (data)) {
+    ViviCodeValue *identifier;
+    const char *method;
+
+    parse_identifier (data, &identifier);
+    // FIXME
+    method = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
+	  VIVI_CODE_GET (identifier)->name));
+    if (g_ascii_strcasecmp (method, "GET") != 0 &&
+	g_ascii_strcasecmp (method, "POST") != 0)
+      vivi_parser_error (data, "Invalid URL method: %s\n", method);
+    g_object_unref (identifier);
+    *value = vivi_code_constant_new_string (method);
+  } else if (peek_string_literal (data)) {
+    parse_string_literal (data, value);
+  } else {
+    vivi_parser_error_unexpected_or (data, TOKEN_IDENTIFIER, TOKEN_STRING,
+	TOKEN_NONE);
+    *value = vivi_code_constant_new_string ("DEFAULT");
+  }
+}*/
+
+typedef ViviCodeStatement *(*NewFunctionVoid) (void);
+typedef ViviCodeStatement *(*NewFunctionValue) (ViviCodeValue *value);
+
+typedef struct {
+  gboolean			return_value;
+  const char *			name;
+  NewFunctionVoid		constructor_void;
+  NewFunctionValue		constructor_value;
+  ParseStatementFunction	parse_custom;
+} SpecialFunction;
+
+static const SpecialFunction special_functions[] = {
+  //{ FALSE, "callFrame",          NULL, vivi_code_call_frame_new, NULL },
+  //{ FALSE, "duplicateMovieClip", NULL, NULL, parse_duplicate_movie_clip },
+  //{ FALSE, "getURL1",            NULL, NULL, parse_get_url1 },
+  //{ FALSE, "getURL",             NULL, NULL, parse_get_url },
+  //{ FALSE, "gotoAndPlay",        NULL, vivi_code_goto_and_play_new, NULL },
+  //{ FALSE, "gotoAndStop",        NULL, vivi_code_goto_and_stop_new, NULL },
+  //{ FALSE, "loadMovie",          NULL, NULL, parse_load_movie },
+  //{ FALSE, "loadMovieNum",       NULL, NULL, parse_load_movie_num },
+  //{ FALSE, "loadVariables",      NULL, NULL, parse_load_variables },
+  //{ FALSE, "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
+  //{ FALSE, "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
+  { FALSE, "play",               vivi_code_play_new, NULL, NULL },
+  //{ FALSE, "prevFrame",          vivi_code_prev_frame_new, NULL, NULL },
+  //{ FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
+  //{ FALSE, "setProperty",        NULL, NULL, parse_set_property },
+  //{ FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
+  //{ FALSE, "startDrag",          NULL, NULL, parse_start_drag },
+  //{ FALSE, "stopDrag",           NULL, vivi_code_stop_drag_new, NULL },
+  //{ FALSE, "stop",               NULL, vivi_code_stop_new, NULL },
+  //{ FALSE, "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
+  //{ FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
+  { FALSE, "trace",              NULL, vivi_code_trace_new, NULL }//,
+  //{ TRUE,  "concat",             NULL, NULL, parse_concat },
+  //{ TRUE,  "substring",          NULL, NULL, parse_substring },
+  //{ TRUE,  "getProperty",        NULL, NULL, parse_get_property },
+  //{ TRUE,  "targetPath",         NULL, vivi_code_target_path_new, NULL },
+  //{ TRUE,  "eval",               NULL, vivi_code_eval_new, NULL },
+  //{ TRUE,  "getTimer",           vivi_code_get_timer_new, NULL, NULL },
+  //{ TRUE,  "random",             NULL, vivi_code_random_new, NULL },
+  //{ TRUE,  "length",             NULL, vivi_code_length_new, NULL },
+  //{ TRUE,  "int",                NULL, vivi_code_int_new, NULL },
+  //{ TRUE,  "ord",                NULL, vivi_code_ord_new, NULL },
+  //{ TRUE,  "chr",                NULL, vivi_code_chr_new, NULL },
+  //{ TRUE,  "typeOf",             NULL, vivi_code_type_of_new, NULL }
+};
+
+static gboolean
+peek_special_statement (ParseData *data)
+{
+  guint i;
+  const char *identifier;
+
+  if (!peek_token (data, TOKEN_IDENTIFIER))
+    return FALSE;
+
+  identifier = data->scanner->next_value.v_identifier;
+
+  // TODO: Check that ( follows?
+
+  for (i = 0; i < G_N_ELEMENTS (special_functions); i++) {
+    if (special_functions[i].return_value == FALSE &&
+	g_ascii_strcasecmp (identifier, special_functions[i].name) == 0)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+static void
+parse_special_statement (ParseData *data, ViviCodeStatement **statement)
+{
+  guint i;
+  const char *identifier;
+  ViviCodeValue *value, *argument;
+  ViviCodeStatement *argument_statement;
+
+  parse_identifier (data, &value);
+  identifier = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
+	VIVI_CODE_GET (value)->name));
+  g_object_unref (value);
+
+  for (i = 0; i < G_N_ELEMENTS (special_functions); i++) {
+    if (special_functions[i].return_value == FALSE &&
+        g_ascii_strcasecmp (identifier, special_functions[i].name) == 0)
+      break;
+  }
+  if (i >= G_N_ELEMENTS (special_functions)) {
+    vivi_parser_error (data, "Unknown special statement: %s", identifier);
+    i = 0;
+  }
+
+  if (special_functions[i].parse_custom != NULL) {
+    special_functions[i].parse_custom (data, statement);
+    return;
+  }
+//
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  if (special_functions[i].constructor_value != NULL)
+    parse_assignment_expression (data, &argument, &argument_statement);
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  parse_automatic_semicolon (data);
+
+  if (special_functions[i].constructor_value != NULL) {
+    *statement = special_functions[i].constructor_value (argument);
+    g_object_unref (argument);
+    *statement = vivi_parser_join_statements (argument_statement, *statement);
+  } else {
+    g_assert (special_functions[i].constructor_void != NULL);
+    *statement = special_functions[i].constructor_void ();
+  }
+}
+
 // expression
 
 static const struct {
@@ -1649,34 +1797,6 @@ parse_expression (ParseData *data, ViviCodeValue **value,
 
 // statement
 
-static gboolean
-peek_trace_statement (ParseData *data)
-{
-  return peek_token (data, TOKEN_TRACE);
-}
-
-static void
-parse_trace_statement (ParseData *data, ViviCodeStatement **statement)
-{
-  ViviCodeValue *value;
-  ViviCodeStatement *expression_statement;
-
-  vivi_parser_start_code_token (data);
-
-  parse_token (data, TOKEN_TRACE);
-  parse_token (data, TOKEN_PARENTHESIS_LEFT);
-  parse_expression (data, &value, &expression_statement);
-  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
-  parse_automatic_semicolon (data);
-
-  *statement = vivi_code_trace_new (value);
-  g_object_unref (value);
-
-  vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*statement));
-
-  *statement = vivi_parser_join_statements (expression_statement, *statement);
-}
-
 static void
 parse_continue_or_break_statement (ParseData *data,
     ViviCodeStatement **statement, ViviParserScannerToken token)
@@ -2095,6 +2215,7 @@ static const struct {
   PeekFunction peek;
   ParseStatementFunction parse;
 } statement_functions[] = {
+  { peek_special_statement, parse_special_statement },
   { peek_block, parse_block },
   { peek_variable_statement, parse_variable_statement },
   { peek_empty_statement, parse_empty_statement },
@@ -2108,7 +2229,6 @@ static const struct {
   //{ peek_switch_statement, parse_switch_statement },
   { peek_throw_statement, parse_throw_statement },
   //{ peek_try_statement, parse_try_statement },
-  { peek_trace_statement, parse_trace_statement },
   { NULL, NULL }
 };
 
diff --git a/vivified/code/vivi_parser_scanner.c b/vivified/code/vivi_parser_scanner.c
index a26a5cc..3582105 100644
--- a/vivified/code/vivi_parser_scanner.c
+++ b/vivified/code/vivi_parser_scanner.c
@@ -202,7 +202,6 @@ static const struct {
 
   // ActionScript specific
   { TOKEN_UNDEFINED, "undefined" },
-  { TOKEN_TRACE, "trace" },
 
   { TOKEN_LAST, NULL }
 };
diff --git a/vivified/code/vivi_parser_scanner.h b/vivified/code/vivi_parser_scanner.h
index 5b1e96b..073bfa9 100644
--- a/vivified/code/vivi_parser_scanner.h
+++ b/vivified/code/vivi_parser_scanner.h
@@ -143,7 +143,6 @@ typedef enum {
 
   // ActionScript specific
   TOKEN_UNDEFINED,
-  TOKEN_TRACE,
 
   TOKEN_LAST
 } ViviParserScannerToken;
diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index f042a4f..8b62e1d 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -197,7 +197,6 @@ identifier_part		[$_a-zA-Z0-9]
 "volatile"		{ count (); return TOKEN_RESERVED_KEYWORD; }
 
 "undefined"		{ count (); return TOKEN_UNDEFINED; }
-"trace"			{ count (); return TOKEN_TRACE; }
 
 "null"			{ count (); return TOKEN_NULL; }
 "true"			{
commit 90341d81368c253d0027ff8c82568cc41d82b33f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Apr 13 14:24:19 2008 +0300

    _lockroot doesn't have an effect if both _level0 and the movie are version 6

diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 693b5c0..15caa70 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -983,10 +983,19 @@ swfdec_movie_get_by_name (SwfdecMovie *movie, const char *name, gboolean unnamed
 SwfdecMovie *
 swfdec_movie_get_root (SwfdecMovie *movie)
 {
+  SwfdecMovie *real_root;
+
   g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), NULL);
 
-  while (movie->parent && !movie->lockroot)
+  real_root = movie;
+  while (real_root->parent)
+    real_root = real_root->parent;
+
+  while (movie->parent && !(movie->lockroot &&
+	(swfdec_movie_get_version (movie) != 6 ||
+	 swfdec_movie_get_version (real_root) != 6))) {
     movie = movie->parent;
+  }
 
   return movie;
 }
commit 1d432e53dd69aeebf62ed2be71b6cc9176112c6e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Apr 12 19:46:30 2008 +0300

    Improve the movieclip-lockroot-loadmovie test case

diff --git a/test/trace/movieclip-lockroot-loadmovie-6.swf b/test/trace/movieclip-lockroot-loadmovie-6.swf
index d198cd6..0881501 100644
Binary files a/test/trace/movieclip-lockroot-loadmovie-6.swf and b/test/trace/movieclip-lockroot-loadmovie-6.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-6.swf.trace b/test/trace/movieclip-lockroot-loadmovie-6.swf.trace
index dd0c666..56b88da 100644
--- a/test/trace/movieclip-lockroot-loadmovie-6.swf.trace
+++ b/test/trace/movieclip-lockroot-loadmovie-6.swf.trace
@@ -1,8 +1,39 @@
+m
+false
+parent
+m_8
 true
 undefined
+m_7
 true
 undefined
+m_6
 true
 parent
+m_6_8
+true
+undefined
+m_6_7
+true
+undefined
+m_6_6
 true
 parent
+m_7_8
+true
+undefined
+m_7_7
+true
+undefined
+m_7_6
+true
+undefined
+m_8_8
+true
+undefined
+m_8_7
+true
+undefined
+m_8_6
+true
+undefined
diff --git a/test/trace/movieclip-lockroot-loadmovie-7.swf b/test/trace/movieclip-lockroot-loadmovie-7.swf
index f88fca7..d89efd6 100644
Binary files a/test/trace/movieclip-lockroot-loadmovie-7.swf and b/test/trace/movieclip-lockroot-loadmovie-7.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-7.swf.trace b/test/trace/movieclip-lockroot-loadmovie-7.swf.trace
index 758e213..82a236e 100644
--- a/test/trace/movieclip-lockroot-loadmovie-7.swf.trace
+++ b/test/trace/movieclip-lockroot-loadmovie-7.swf.trace
@@ -1,8 +1,39 @@
+m
+false
+parent
+m_8
 true
 undefined
+m_7
 true
 undefined
+m_6
 true
 undefined
+m_6_8
+true
+undefined
+m_6_7
+true
+undefined
+m_6_6
+true
+undefined
+m_7_8
+true
+undefined
+m_7_7
+true
+undefined
+m_7_6
+true
+undefined
+m_8_8
+true
+undefined
+m_8_7
+true
+undefined
+m_8_6
 true
 undefined
diff --git a/test/trace/movieclip-lockroot-loadmovie-8.swf b/test/trace/movieclip-lockroot-loadmovie-8.swf
index 7acb7bc..896f5ce 100644
Binary files a/test/trace/movieclip-lockroot-loadmovie-8.swf and b/test/trace/movieclip-lockroot-loadmovie-8.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-8.swf.trace b/test/trace/movieclip-lockroot-loadmovie-8.swf.trace
index 758e213..82a236e 100644
--- a/test/trace/movieclip-lockroot-loadmovie-8.swf.trace
+++ b/test/trace/movieclip-lockroot-loadmovie-8.swf.trace
@@ -1,8 +1,39 @@
+m
+false
+parent
+m_8
 true
 undefined
+m_7
 true
 undefined
+m_6
 true
 undefined
+m_6_8
+true
+undefined
+m_6_7
+true
+undefined
+m_6_6
+true
+undefined
+m_7_8
+true
+undefined
+m_7_7
+true
+undefined
+m_7_6
+true
+undefined
+m_8_8
+true
+undefined
+m_8_7
+true
+undefined
+m_8_6
 true
 undefined
diff --git a/test/trace/movieclip-lockroot-loadmovie.as b/test/trace/movieclip-lockroot-loadmovie.as
index 35e305e..ef442f8 100644
--- a/test/trace/movieclip-lockroot-loadmovie.as
+++ b/test/trace/movieclip-lockroot-loadmovie.as
@@ -1,14 +1,20 @@
 // makeswf -v 7 -s 200x150 -r 1 -o movieclip-lockroot-loadmovie.swf movieclip-lockroot-loadmovie.as
 
-if (_level0.value == undefined) {
-  _root.value = "parent";
-  for (i = 5; i <= 8; i++) {
-    var c = this.createEmptyMovieClip ("m" + i, i);
+if (this._name == "") {
+  _level0.value = "parent";
+  this._name = "m";
+}
+
+trace (this._name);
+trace (this._lockroot);
+trace (_root.value);
+
+if (this._name.length <= 3) {
+  for (i = 6; i <= 8; i++) {
+    var c = this.createEmptyMovieClip (this._name + "_" + i, i);
     c._lockroot = true;
-    loadMovie ("movieclip-lockroot-loadmovie-" + i + ".swf", "m" + i);
+    loadMovie ("movieclip-lockroot-loadmovie-" + i + ".swf", c);
   }
 } else {
-  trace (this._lockroot);
-  trace (_root.value);
   getURL ("FSCommand:quit", "");
 }
commit 2005212b1e1c297510d5674067f438605adff7ae
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Apr 12 18:58:49 2008 +0300

    Add two test cases for MovieClip's _lockroot property

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 29997c0..efed79e 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -1699,6 +1699,22 @@ EXTRA_DIST = \
 	movieclip-get-instance-at-depth-7.swf.trace \
 	movieclip-get-instance-at-depth-8.swf \
 	movieclip-get-instance-at-depth-8.swf.trace \
+	movieclip-lockroot.as \
+	movieclip-lockroot-5.swf \
+	movieclip-lockroot-5.swf.trace \
+	movieclip-lockroot-6.swf \
+	movieclip-lockroot-6.swf.trace \
+	movieclip-lockroot-7.swf \
+	movieclip-lockroot-7.swf.trace \
+	movieclip-lockroot-8.swf \
+	movieclip-lockroot-8.swf.trace \
+	movieclip-lockroot-loadmovie.as \
+	movieclip-lockroot-loadmovie-6.swf \
+	movieclip-lockroot-loadmovie-6.swf.trace \
+	movieclip-lockroot-loadmovie-7.swf \
+	movieclip-lockroot-loadmovie-7.swf.trace \
+	movieclip-lockroot-loadmovie-8.swf \
+	movieclip-lockroot-loadmovie-8.swf.trace \
 	movieclip-set-prototype.c \
 	movieclip-set-prototype-5.swf \
 	movieclip-set-prototype-5.swf.trace \
diff --git a/test/trace/movieclip-lockroot-5.swf b/test/trace/movieclip-lockroot-5.swf
new file mode 100644
index 0000000..8422923
Binary files /dev/null and b/test/trace/movieclip-lockroot-5.swf differ
diff --git a/test/trace/movieclip-lockroot-5.swf.trace b/test/trace/movieclip-lockroot-5.swf.trace
new file mode 100644
index 0000000..1a87c1e
--- /dev/null
+++ b/test/trace/movieclip-lockroot-5.swf.trace
@@ -0,0 +1,3 @@
+undefined
+undefined
+undefined
diff --git a/test/trace/movieclip-lockroot-6.swf b/test/trace/movieclip-lockroot-6.swf
new file mode 100644
index 0000000..6b581e0
Binary files /dev/null and b/test/trace/movieclip-lockroot-6.swf differ
diff --git a/test/trace/movieclip-lockroot-6.swf.trace b/test/trace/movieclip-lockroot-6.swf.trace
new file mode 100644
index 0000000..5a92569
--- /dev/null
+++ b/test/trace/movieclip-lockroot-6.swf.trace
@@ -0,0 +1,3 @@
+parent
+parent
+parent
diff --git a/test/trace/movieclip-lockroot-7.swf b/test/trace/movieclip-lockroot-7.swf
new file mode 100644
index 0000000..09d6182
Binary files /dev/null and b/test/trace/movieclip-lockroot-7.swf differ
diff --git a/test/trace/movieclip-lockroot-7.swf.trace b/test/trace/movieclip-lockroot-7.swf.trace
new file mode 100644
index 0000000..caa46c8
--- /dev/null
+++ b/test/trace/movieclip-lockroot-7.swf.trace
@@ -0,0 +1,3 @@
+parent
+a
+b
diff --git a/test/trace/movieclip-lockroot-8.swf b/test/trace/movieclip-lockroot-8.swf
new file mode 100644
index 0000000..f580642
Binary files /dev/null and b/test/trace/movieclip-lockroot-8.swf differ
diff --git a/test/trace/movieclip-lockroot-8.swf.trace b/test/trace/movieclip-lockroot-8.swf.trace
new file mode 100644
index 0000000..caa46c8
--- /dev/null
+++ b/test/trace/movieclip-lockroot-8.swf.trace
@@ -0,0 +1,3 @@
+parent
+a
+b
diff --git a/test/trace/movieclip-lockroot-loadmovie-6.swf b/test/trace/movieclip-lockroot-loadmovie-6.swf
new file mode 100644
index 0000000..d198cd6
Binary files /dev/null and b/test/trace/movieclip-lockroot-loadmovie-6.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-6.swf.trace b/test/trace/movieclip-lockroot-loadmovie-6.swf.trace
new file mode 100644
index 0000000..dd0c666
--- /dev/null
+++ b/test/trace/movieclip-lockroot-loadmovie-6.swf.trace
@@ -0,0 +1,8 @@
+true
+undefined
+true
+undefined
+true
+parent
+true
+parent
diff --git a/test/trace/movieclip-lockroot-loadmovie-7.swf b/test/trace/movieclip-lockroot-loadmovie-7.swf
new file mode 100644
index 0000000..f88fca7
Binary files /dev/null and b/test/trace/movieclip-lockroot-loadmovie-7.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-7.swf.trace b/test/trace/movieclip-lockroot-loadmovie-7.swf.trace
new file mode 100644
index 0000000..758e213
--- /dev/null
+++ b/test/trace/movieclip-lockroot-loadmovie-7.swf.trace
@@ -0,0 +1,8 @@
+true
+undefined
+true
+undefined
+true
+undefined
+true
+undefined
diff --git a/test/trace/movieclip-lockroot-loadmovie-8.swf b/test/trace/movieclip-lockroot-loadmovie-8.swf
new file mode 100644
index 0000000..7acb7bc
Binary files /dev/null and b/test/trace/movieclip-lockroot-loadmovie-8.swf differ
diff --git a/test/trace/movieclip-lockroot-loadmovie-8.swf.trace b/test/trace/movieclip-lockroot-loadmovie-8.swf.trace
new file mode 100644
index 0000000..758e213
--- /dev/null
+++ b/test/trace/movieclip-lockroot-loadmovie-8.swf.trace
@@ -0,0 +1,8 @@
+true
+undefined
+true
+undefined
+true
+undefined
+true
+undefined
diff --git a/test/trace/movieclip-lockroot-loadmovie.as b/test/trace/movieclip-lockroot-loadmovie.as
new file mode 100644
index 0000000..35e305e
--- /dev/null
+++ b/test/trace/movieclip-lockroot-loadmovie.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -s 200x150 -r 1 -o movieclip-lockroot-loadmovie.swf movieclip-lockroot-loadmovie.as
+
+if (_level0.value == undefined) {
+  _root.value = "parent";
+  for (i = 5; i <= 8; i++) {
+    var c = this.createEmptyMovieClip ("m" + i, i);
+    c._lockroot = true;
+    loadMovie ("movieclip-lockroot-loadmovie-" + i + ".swf", "m" + i);
+  }
+} else {
+  trace (this._lockroot);
+  trace (_root.value);
+  getURL ("FSCommand:quit", "");
+}
diff --git a/test/trace/movieclip-lockroot.as b/test/trace/movieclip-lockroot.as
new file mode 100644
index 0000000..594d8e6
--- /dev/null
+++ b/test/trace/movieclip-lockroot.as
@@ -0,0 +1,15 @@
+// makeswf -v 7 -r 1 -o crash-0.6.0-moviecliploader.swf crash-0.6.0-moviecliploader.as
+
+this.createEmptyMovieClip ("a", 0);
+var b = a.createEmptyMovieClip ("b", 1);
+this.value = "parent";
+a.value = "a";
+b.value = "b";
+
+trace (b._root.value);
+a._lockroot = true;
+trace (b._root.value);
+b._lockroot = true;
+trace (b._root.value);
+
+getURL ("FSCommand:quit", "");
commit 28dcb3dc12e1e26d1e8f84b8e3a064e248213019
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Apr 12 18:47:31 2008 +0300

    Implement MovieClip's _lockroot property

diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 27e6486..693b5c0 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -985,7 +985,7 @@ swfdec_movie_get_root (SwfdecMovie *movie)
 {
   g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), NULL);
 
-  while (movie->parent)
+  while (movie->parent && !movie->lockroot)
     movie = movie->parent;
 
   return movie;
diff --git a/swfdec/swfdec_movie.h b/swfdec/swfdec_movie.h
index f0f12d4..e23557d 100644
--- a/swfdec/swfdec_movie.h
+++ b/swfdec/swfdec_movie.h
@@ -112,6 +112,7 @@ struct _SwfdecMovie {
 
   /* parenting information */
   SwfdecMovie *		parent;			/* movie that contains us or NULL for root movies */
+  gboolean		lockroot;		/* when looking for _root we should use this movie, even if it has a parent */
   SwfdecResource *	resource;     		/* the resource that created us */
 
   /* positioning - the values are applied in this order */
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index 4285b02..d9e1259 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -186,6 +186,7 @@ swfdec_resource_replace_movie (SwfdecSpriteMovie *movie, SwfdecResource *resourc
   copy->xscale = mov->xscale;
   copy->yscale = mov->yscale;
   copy->rotation = mov->rotation;
+  copy->lockroot = mov->lockroot;
   /* FIXME: are events copied? If so, wouldn't that be a security issue? */
   swfdec_movie_set_static_properties (copy, &mov->original_transform,
       &mov->original_ctrans, mov->original_ratio, mov->clip_depth, 
diff --git a/swfdec/swfdec_sprite_movie_as.c b/swfdec/swfdec_sprite_movie_as.c
index c5e1fb1..c7146f5 100644
--- a/swfdec/swfdec_sprite_movie_as.c
+++ b/swfdec/swfdec_sprite_movie_as.c
@@ -59,7 +59,11 @@ void
 swfdec_sprite_movie_get__lockroot (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SWFDEC_STUB ("MovieClip._lockroot (get)");
+  SwfdecMovie *movie;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE, &movie, "");
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (rval, movie->lockroot);
 }
 
 SWFDEC_AS_NATIVE (900, 301, swfdec_sprite_movie_set__lockroot)
@@ -67,7 +71,12 @@ void
 swfdec_sprite_movie_set__lockroot (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SWFDEC_STUB ("MovieClip._lockroot (set)");
+  SwfdecMovie *movie;
+  gboolean lockroot;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE, &movie, "b", &lockroot);
+
+  movie->lockroot = lockroot;
 }
 
 SWFDEC_AS_NATIVE (900, 401, swfdec_sprite_movie_get_cacheAsBitmap)


More information about the Swfdec-commits mailing list