📄 swfdec_as_object.c
字号:
{ SwfdecAsFunction *function; SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (type == 0 || g_type_is_a (type, SWFDEC_TYPE_AS_OBJECT), NULL); g_return_val_if_fail (construct_type == 0 || g_type_is_a (construct_type, SWFDEC_TYPE_AS_OBJECT), NULL); g_return_val_if_fail (prototype == NULL || SWFDEC_IS_AS_OBJECT (prototype), NULL); if (!native) native = swfdec_as_object_do_nothing; function = swfdec_as_native_function_new (object->context, name, native, min_args, prototype); if (function == NULL) return NULL; if (type != 0) swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (function), type); if (construct_type != 0) swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (function), construct_type); name = swfdec_as_context_get_string (object->context, name); SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function)); /* FIXME: I'd like to make sure no such property exists yet */ swfdec_as_object_set_variable_and_flags (object, name, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); return function;}/** * swfdec_as_object_run: * @object: a #SwfdecAsObject * @script: script to execute * * Executes the given @script with @object as this pointer. **/voidswfdec_as_object_run (SwfdecAsObject *object, SwfdecScript *script){ SwfdecAsContext *context; SwfdecAsFrame *frame; g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (script != NULL); context = object->context; frame = swfdec_as_frame_new (context, script); if (frame == NULL) return; swfdec_as_frame_set_this (frame, object); swfdec_as_frame_preload (frame); swfdec_as_context_run (context); swfdec_as_stack_pop (context);}/** * swfdec_as_object_call: * @object: a #SwfdecAsObject * @name: garbage-collected string naming the function to call. * @argc: number of arguments to provide to function * @argv: arguments or %NULL when @argc is 0 * @return_value: location to take the return value of the call or %NULL to * ignore the return value. * * Calls the function named @name on the given object. This function is * essentially equal to the folloeing Actionscript code: * <informalexample><programlisting> * @return_value = @object.@name (@argv[0], ..., @argv[argc-1]); * </programlisting></informalexample> **/voidswfdec_as_object_call (SwfdecAsObject *object, const char *name, guint argc, SwfdecAsValue *argv, SwfdecAsValue *return_value){ static SwfdecAsValue tmp; /* ignored */ SwfdecAsFunction *fun; g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (name != NULL); g_return_if_fail (argc == 0 || argv != NULL); if (return_value) SWFDEC_AS_VALUE_SET_UNDEFINED (return_value); swfdec_as_object_get_variable (object, name, &tmp); if (!SWFDEC_AS_VALUE_IS_OBJECT (&tmp)) return; fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&tmp); if (!SWFDEC_IS_AS_FUNCTION (fun)) return; swfdec_as_function_call (fun, object, argc, argv, return_value ? return_value : &tmp); swfdec_as_context_run (object->context);}/** * swfdec_as_object_has_function: * @object: a #SwfdecAsObject * @name: garbage-collected name of th function * * Convenience function that checks of @object has a variable that references * a function. * * Returns: %TRUE if object.name is a function. **/gbooleanswfdec_as_object_has_function (SwfdecAsObject *object, const char *name){ SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE); g_return_val_if_fail (name != NULL, FALSE); swfdec_as_object_get_variable (object, name, &val); if (!SWFDEC_AS_VALUE_IS_OBJECT (&val)) return FALSE; return SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (&val));}/** * swfdec_as_object_create: * @fun: constructor * @n_args: number of arguments * @args: arguments to pass to constructor * * Creates a new object for the given constructor and pushes the constructor on * top of the stack. To actually run the constructor, you need to call * swfdec_as_context_run(). After the constructor has been run, the new object * will be pushed to the top of the stack. **/voidswfdec_as_object_create (SwfdecAsFunction *fun, guint n_args, const SwfdecAsValue *args){ SwfdecAsValue val; SwfdecAsObject *new; SwfdecAsContext *context; SwfdecAsFunction *cur; guint size; GType type = 0; g_return_if_fail (SWFDEC_IS_AS_FUNCTION (fun)); context = SWFDEC_AS_OBJECT (fun)->context; cur = fun; do { if (SWFDEC_IS_AS_NATIVE_FUNCTION (cur)) { SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (cur); if (native->construct_size) { type = native->construct_type; size = native->construct_size; break; } } swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), SWFDEC_AS_STR_prototype, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { SwfdecAsObject *proto = SWFDEC_AS_VALUE_GET_OBJECT (&val); swfdec_as_object_get_variable (proto, SWFDEC_AS_STR___constructor__, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { cur = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val); if (SWFDEC_IS_AS_FUNCTION (cur)) { continue; } } } cur = NULL; } while (type == 0 && cur != NULL); if (type == 0) { type = SWFDEC_TYPE_AS_OBJECT; size = sizeof (SwfdecAsObject); } if (swfdec_as_context_use_mem (context, size)) { new = g_object_new (type, NULL); swfdec_as_object_add (new, context, size); /* set initial variables */ if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val)) { swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR___proto__, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); } SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun)); if (context->version < 7) { swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR_constructor, &val, SWFDEC_AS_VARIABLE_HIDDEN); } if (context->version <= 5) SWFDEC_AS_VALUE_SET_UNDEFINED (&val); swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR___constructor__, &val, SWFDEC_AS_VARIABLE_HIDDEN); } else { /* need to do this, since we must push something to the frame stack */ new = NULL; } swfdec_as_function_call (fun, new, n_args, args, NULL); context->frame->construct = TRUE;}/** * swfdec_as_object_set_constructor: * @object: a #SwfdecAsObject * @construct: the constructor of @object * * Sets the constructor variables for @object. Most objects get these * variables set automatically, but for objects you created yourself, you want * to call this function. This is essentially the same as the following script * code: * |[ object.constructor = construct; * object.__proto__ = construct.prototype; ]| **/voidswfdec_as_object_set_constructor (SwfdecAsObject *object, SwfdecAsObject *construct){ SwfdecAsValue val; SwfdecAsObject *proto; g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (SWFDEC_IS_AS_OBJECT (construct)); swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (construct), SWFDEC_AS_STR_prototype, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { proto = SWFDEC_AS_VALUE_GET_OBJECT (&val); } else { SWFDEC_WARNING ("constructor has no prototype, using Object.prototype"); proto = object->context->Object_prototype; } SWFDEC_AS_VALUE_SET_OBJECT (&val, construct); swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_constructor, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); SWFDEC_AS_VALUE_SET_OBJECT (&val, proto); swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);}/** * swfdec_as_object_add_variable: * @object: a #SwfdecAsObject * @variable: name of the variable * @get: getter function to call when reading the variable * @set: setter function to call when writing the variable or %NULL if read-only * * Adds a variable to @object in the same way as the Actionscript code * "object.addProperty()" would do. Accessing the variable will from now on be * handled by calling the @get or @set functions. A previous value of the * variable or a previous call to this function will be overwritten. **/voidswfdec_as_object_add_variable (SwfdecAsObject *object, const char *variable, SwfdecAsFunction *get, SwfdecAsFunction *set){ SwfdecAsVariable *var; g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (variable != NULL); g_return_if_fail (SWFDEC_IS_AS_FUNCTION (get)); g_return_if_fail (set == NULL || SWFDEC_IS_AS_FUNCTION (set)); var = swfdec_as_object_hash_lookup (object, variable); if (var == NULL) var = swfdec_as_object_hash_create (object, variable, 0); if (var == NULL) return; var->get = get; var->set = set;}/*** AS CODE ***/static voidswfdec_as_object_addProperty (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){ SwfdecAsFunction *get, *set; const char *name; SWFDEC_AS_VALUE_SET_BOOLEAN (retval, FALSE); if (argc < 3) return; name = swfdec_as_value_to_string (cx, &argv[0]); if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[1]) || !SWFDEC_IS_AS_FUNCTION ((get = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[1])))) return; if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[2])) { set = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[2]); if (!SWFDEC_IS_AS_FUNCTION (set)) return; } else if (SWFDEC_AS_VALUE_IS_NULL (&argv[2])) { set = NULL; } else { return; } swfdec_as_object_add_variable (object, name, get, set); SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE);}static voidswfdec_as_object_hasOwnProperty (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){ const char *name; name = swfdec_as_value_to_string (object->context, &argv[0]); if (swfdec_as_object_hash_lookup (object, name)) SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE); else SWFDEC_AS_VALUE_SET_BOOLEAN (retval, FALSE);}static voidswfdec_as_object_valueOf (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){ SWFDEC_AS_VALUE_SET_OBJECT (retval, object);}static voidswfdec_as_object_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){ if (SWFDEC_IS_AS_FUNCTION (object)) { SWFDEC_AS_VALUE_SET_STRING (retval, SWFDEC_AS_STR__type_Function_); } else { SWFDEC_AS_VALUE_SET_STRING (retval, SWFDEC_AS_STR__object_Object_); }}voidswfdec_as_object_init_context (SwfdecAsContext *context, guint version){ SwfdecAsValue val; SwfdecAsObject *object, *proto; proto = swfdec_as_object_new_empty (context); if (!proto) return; object = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_Object, 0, NULL, 0)); if (!object) return; context->Object = object; context->Object_prototype = proto; SWFDEC_AS_VALUE_SET_OBJECT (&val, proto); /* first, set our own */ swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_prototype, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT | SWFDEC_AS_VARIABLE_CONSTANT); if (context->Function_prototype) { /* then finish the function prototype (use this order or * SWFDEC_AS_VARIABLE_CONSTANT won't let us */ swfdec_as_object_set_variable_and_flags (context->Function_prototype, SWFDEC_AS_STR___proto__, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); } SWFDEC_AS_VALUE_SET_OBJECT (&val, object); swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); if (version > 5) { swfdec_as_object_add_function (proto, SWFDEC_AS_STR_addProperty, SWFDEC_TYPE_AS_OBJECT, swfdec_as_object_addProperty, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_hasOwnProperty, SWFDEC_TYPE_AS_OBJECT, swfdec_as_object_hasOwnProperty, 1); } swfdec_as_object_add_function (proto, SWFDEC_AS_STR_valueOf, SWFDEC_TYPE_AS_OBJECT, swfdec_as_object_valueOf, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, SWFDEC_TYPE_AS_OBJECT, swfdec_as_object_toString, 0);}/** * swfdec_as_object_get_debug: * @object: a #SwfdecAsObject * * Gets a representation string suitable for debugging. This function is * guaranteed to not modify the state of the script engine, unlike * swfdec_as_value_to_string() for example. * * Returns: A newly allocated string. Free it with g_free() after use. **/char *swfdec_as_object_get_debug (SwfdecAsObject *object){ SwfdecAsObjectClass *klass; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); klass = SWFDEC_AS_OBJECT_GET_CLASS (object); return klass->debug (object);}/** * swfdec_as_object_resolve: * @object: a #SwfdecAsObject * * Resolves the object to its real object. Some internal objects should not be * exposed to scripts, for example #SwfdecAsFrame objects. If an object you want * to expose might be internal, call this function to resolve it to an object * that is safe to expose. * * Returns: a non-internal object **/SwfdecAsObject *swfdec_as_object_resolve (SwfdecAsObject *object){ SwfdecAsObjectClass *klass; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); klass = SWFDEC_AS_OBJECT_GET_CLASS (object); if (klass->resolve == NULL) return object; return klass->resolve (object);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -