⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_as_context.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 3 页
字号:
  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  if (context->state == SWFDEC_AS_CONTEXT_ABORTED)    return;  g_return_if_fail (context->frame == NULL);  if (swfdec_as_context_needs_gc (context))    swfdec_as_context_gc (context);}/*** SWFDEC_AS_CONTEXT ***/enum {  TRACE,  LAST_SIGNAL};enum {  PROP_0,  PROP_DEBUGGER,  PROP_UNTIL_GC};G_DEFINE_TYPE (SwfdecAsContext, swfdec_as_context, G_TYPE_OBJECT)static guint signals[LAST_SIGNAL] = { 0, };static voidswfdec_as_context_get_property (GObject *object, guint param_id, GValue *value,     GParamSpec * pspec){  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);    switch (param_id) {    case PROP_DEBUGGER:      g_value_set_object (value, context->debugger);      break;    case PROP_UNTIL_GC:      g_value_set_ulong (value, (gulong) context->memory_until_gc);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);      break;  }}static voidswfdec_as_context_set_property (GObject *object, guint param_id, const GValue *value,     GParamSpec * pspec){  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);    switch (param_id) {    case PROP_DEBUGGER:      context->debugger = SWFDEC_AS_DEBUGGER (g_value_dup_object (value));      break;    case PROP_UNTIL_GC:      context->memory_until_gc = g_value_get_ulong (value);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);      break;  }}static voidswfdec_as_context_dispose (GObject *object){  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);  while (context->stack)    swfdec_as_stack_pop_segment (context);  swfdec_as_context_collect (context);  if (context->memory != 0) {    g_critical ("%zu bytes of memory left over\n", context->memory);  }  g_assert (g_hash_table_size (context->objects) == 0);  g_hash_table_destroy (context->objects);  g_hash_table_destroy (context->strings);  g_rand_free (context->rand);  if (context->debugger) {    g_object_unref (context->debugger);    context->debugger = NULL;  }  G_OBJECT_CLASS (swfdec_as_context_parent_class)->dispose (object);}static voidswfdec_as_context_class_init (SwfdecAsContextClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  object_class->dispose = swfdec_as_context_dispose;  object_class->get_property = swfdec_as_context_get_property;  object_class->set_property = swfdec_as_context_set_property;  g_object_class_install_property (object_class, PROP_DEBUGGER,      g_param_spec_object ("debugger", "debugger", "debugger used in this player",	  SWFDEC_TYPE_AS_DEBUGGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));  g_object_class_install_property (object_class, PROP_UNTIL_GC,      g_param_spec_ulong ("memory-until-gc", "memory until gc", 	  "amount of bytes that need to be allocated before garbage collection triggers",	  0, G_MAXULONG, 8 * 1024 * 1024, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));  /**   * SwfdecAsContext::trace:   * @context: the #SwfdecAsContext affected   * @text: the debugging string   *   * Emits a debugging string while running. The effect of calling any swfdec    * functions on the emitting @context is undefined.   */  signals[TRACE] = g_signal_new ("trace", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING,      G_TYPE_NONE, 1, G_TYPE_STRING);  klass->mark = swfdec_as_context_do_mark;}static voidswfdec_as_context_init (SwfdecAsContext *context){  const char *s;  context->strings = g_hash_table_new (g_str_hash, g_str_equal);  context->objects = g_hash_table_new (g_direct_hash, g_direct_equal);  for (s = swfdec_as_strings; *s == '\2'; s += strlen (s) + 1) {    g_hash_table_insert (context->strings, (char *) s + 1, (char *) s);  }  g_assert (*s == 0);  context->global = swfdec_as_object_new_empty (context);  context->rand = g_rand_new ();  g_get_current_time (&context->start_time);}/*** STRINGS ***/static const char *swfdec_as_context_create_string (SwfdecAsContext *context, const char *string, gsize len){  char *new;    if (!swfdec_as_context_use_mem (context, sizeof (char) * (2 + len)))    return SWFDEC_AS_STR_EMPTY;  new = g_slice_alloc (2 + len);  memcpy (&new[1], string, len);  new[len + 1] = 0;  new[0] = 0; /* GC flags */  g_hash_table_insert (context->strings, new + 1, new);  return new + 1;}/** * swfdec_as_context_get_string: * @context: a #SwfdecAsContext * @string: a sting that is not garbage-collected * * Gets the garbage-collected version of @string. You need to call this function * for every not garbage-collected string that you want to use in Swfdecs script * interpreter. * * Returns: the garbage-collected version of @string **/const char *swfdec_as_context_get_string (SwfdecAsContext *context, const char *string){  const char *ret;  gsize len;  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);  g_return_val_if_fail (string != NULL, NULL);  if (g_hash_table_lookup_extended (context->strings, string, (gpointer) &ret, NULL))    return ret;  len = strlen (string);  return swfdec_as_context_create_string (context, string, len);}/** * swfdec_as_context_give_string: * @context: a #SwfdecAsContext * @string: string to make refcounted * * Takes ownership of @string and returns a refcounted version of the same  * string. This function is the same as swfdec_as_context_get_string(), but  * takes ownership of @string. * * Returns: A refcounted string **/const char *swfdec_as_context_give_string (SwfdecAsContext *context, char *string){  const char *ret;  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);  g_return_val_if_fail (string != NULL, NULL);  ret = swfdec_as_context_get_string (context, string);  g_free (string);  return ret;}/** * swfdec_as_context_is_constructing: * @context: a #SwfdecAsConstruct * * Determines if the contexxt is currently constructing. This information is * used by various constructors to do different things when they are  * constructing and when they are not. The Boolean, Number and String functions * for example setup the newly constructed objects when constructing but only * cast the provided argument when being called. * * Returns: %TRUE if the currently executing frame is a constructor **/gbooleanswfdec_as_context_is_constructing (SwfdecAsContext *context){  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);  return context->frame && context->frame->construct;}/** * swfdec_as_context_get_frame: * @context: a #SwfdecAsContext * * This is a debugging function. It gets the topmost stack frame that is  * currently executing. If no function is executing, %NULL is returned. You can * easily get a backtrace with code like this: * |[for (frame = swfdec_as_context_get_frame (context); frame != NULL;  *     frame = swfdec_as_frame_get_next (frame)) { *   char *s = swfdec_as_object_get_debug (SWFDEC_AS_OBJECT (frame)); *   g_print ("%s\n", s); *   g_free (s); * }]| * * Returns: the currently executing frame or %NULL if none **/SwfdecAsFrame *swfdec_as_context_get_frame (SwfdecAsContext *context){  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);  return context->frame;}/** * swfdec_as_context_get_time: * @context: a #SwfdecAsContext * @tv: a #GTimeVal to be set to the context's time * * This function queries the time to be used inside this context. By default, * this is the same as g_get_current_time(), but it may be overwriten to allow * things such as slower or faster playback. **/voidswfdec_as_context_get_time (SwfdecAsContext *context, GTimeVal *tv){  SwfdecAsContextClass *klass;  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  g_return_if_fail (tv != NULL);  klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);  if (klass->get_time)    klass->get_time (context, tv);  else    g_get_current_time (tv);}/** * swfdec_as_context_run: * @context: a #SwfdecAsContext * * Continues running the script engine. Executing code in this engine works * in 2 steps: First, you push the frame to be executed onto the stack, then * you call this function to execute it. So this function is the single entry * point to script execution. This might be helpful when debugging your  * application.  * <note>A lot of convenience functions like swfdec_as_object_run() call this  * function automatically.</note> **/voidswfdec_as_context_run (SwfdecAsContext *context){  SwfdecAsFrame *frame, *last_frame;  SwfdecScript *script;  const SwfdecActionSpec *spec;  SwfdecActionExec exec;  guint8 *startpc, *pc, *endpc, *nextpc;#ifndef G_DISABLE_ASSERT  SwfdecAsValue *check;#endif  guint action, len;  guint8 *data;  int version;  void (* step) (SwfdecAsDebugger *debugger, SwfdecAsContext *context);  gboolean check_scope; /* some opcodes avoid a scope check */  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  if (context->frame == NULL || context->state == SWFDEC_AS_CONTEXT_ABORTED)    return;  if (context->debugger) {    SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger);    step = klass->step;  } else {    step = NULL;  }  last_frame = context->last_frame;  context->last_frame = context->frame->next;start:  /* setup data */  frame = context->frame;  if (frame == context->last_frame)    goto out;  if (context->call_depth > 256) {    /* we've exceeded our maximum call depth, throw an error and abort */    swfdec_as_context_abort (context, "Stack overflow");    return;  }  if (SWFDEC_IS_AS_NATIVE_FUNCTION (frame->function)) {    SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (frame->function);    SwfdecAsValue rval = { 0, };    if (frame->argc >= native->min_args && 	(native->type == 0 || 	 g_type_is_a (G_OBJECT_TYPE (frame->thisp), native->type))) {      SwfdecAsValue *argv;      /* accumulate argv */      if (frame->argc == 0 || frame->argv != NULL) {	/* FIXME FIXME FIXME: no casting here please! */	argv = (SwfdecAsValue *) frame->argv;      } else {	SwfdecAsStack *stack;	SwfdecAsValue *cur;	guint i, n;	if (frame->argc > 128) {	  SWFDEC_FIXME ("allow calling native functions with more than 128 args");	  n = 128;	} else {	  n = frame->argc;	}	argv = g_new (SwfdecAsValue, n);	stack = context->stack;	cur = context->cur;	for (i = 0; i < n; i++) {	  if (cur <= &stack->elements[0]) {	    stack = stack->next;	    cur = &stack->elements[stack->used_elements];	  }	  cur--;	  argv[i] = *cur;	}      }      native->native (context, frame->thisp, frame->argc, 	  argv, &rval);      if (argv != frame->argv)	g_free (argv);    }    swfdec_as_frame_return (frame, &rval);    goto start;  }  g_assert (frame->script);  g_assert (frame->target);  script = frame->script;  version = SWFDEC_AS_EXTRACT_SCRIPT_VERSION (script->version);  context->version = script->version;  startpc = script->buffer->data;  endpc = startpc + script->buffer->length;  pc = frame->pc;  check_scope = TRUE;  while (context->state < SWFDEC_AS_CONTEXT_ABORTED) {    if (pc == endpc) {      swfdec_as_frame_return (frame, NULL);      goto start;    }    if (pc < startpc || pc >= endpc) {      SWFDEC_ERROR ("pc %p not in valid range [%p, %p) anymore", pc, startpc, endpc);      goto error;    }    if (check_scope)      swfdec_as_frame_check_scope (frame);    /* decode next action */    action = *pc;    if (action == 0) {      swfdec_as_frame_return (frame, NULL);      goto start;    }    /* invoke debugger if there is one */    if (step) {      frame->pc = pc;      (* step) (context->debugger, context);      if (frame != context->frame || 	  frame->pc != pc) {	goto start;      }    }    /* prepare action */    spec = swfdec_as_actions + action;    if (action & 0x80) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -