📄 swfdec_as_frame.c
字号:
/* setup stack for previous frame */ if (next) { if (next->stack_begin >= &context->stack->elements[0] && next->stack_begin <= context->cur) { context->base = next->stack_begin; } else { context->base = &context->stack->elements[0]; } } else { g_assert (context->stack->next == NULL); context->base = &context->stack->elements[0]; } /* pop argv if on stack */ if (frame->argv == NULL && frame->argc > 0) { guint i = frame->argc; while (TRUE) { guint n = context->cur - context->base; n = MIN (n, i); swfdec_as_stack_pop_n (context, n); i -= n; if (i == 0) break; swfdec_as_stack_pop_segment (context); } } if (context->debugger) { SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger); if (klass->leave_frame) klass->leave_frame (context->debugger, context, frame, &retval); } /* set return value */ if (frame->return_value) { *frame->return_value = retval; } else { swfdec_as_stack_ensure_free (context, 1); *swfdec_as_stack_push (context) = retval; }}/** * swfdec_as_frame_set_this: * @frame: a #SwfdecAsFrame * @thisp: object to use as the this object * * Sets the object to be used as this pointer. If this function is not called, * the this value will be undefined. * You may only call this function once per @frame and it must be called * directly after creating the frame and before calling swfdec_as_frame_preload(). **/voidswfdec_as_frame_set_this (SwfdecAsFrame *frame, SwfdecAsObject *thisp){ g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); g_return_if_fail (frame->thisp == NULL); g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp)); g_assert (!SWFDEC_IS_AS_SUPER (thisp)); frame->thisp = thisp; if (frame->target == NULL) { frame->target = thisp; frame->original_target = thisp; }}/** * swfdec_as_frame_find_variable: * @frame: a #SwfdecAsFrame * @variable: name of the variable to find * * Finds the given variable in the current scope chain. Returns the first * object in the scope chain that contains this variable in its prototype * chain. If you want to know the explicit object that contains the variable, * you have to call swfdec_as_object_get_variable_and_flags() on the result. * If no such variable exist in the scope chain, %NULL is returned. * <note>The returned object might be an internal object. You probably do not * want to expose it to scripts. Call swfdec_as_object_resolve () on the * returned value to be sure of not having an internal object.</note> * * Returns: the object that contains @variable or %NULL if none. **/SwfdecAsObject *swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const char *variable){ SwfdecAsScope *cur; guint i; SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); g_return_val_if_fail (variable != NULL, NULL); cur = frame->scope; for (i = 0; i < 256; i++) { if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), variable, &val)) return SWFDEC_AS_OBJECT (cur); if (cur->next == NULL) break; cur = cur->next; } if (i == 256) { swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded"); return NULL; } g_assert (SWFDEC_IS_AS_FRAME (cur)); /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target */ if (swfdec_as_object_get_variable (frame->target, variable, &val)) return frame->target; /* 2) the global object */ if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable, &val)) return SWFDEC_AS_OBJECT (frame)->context->global; return NULL;}SwfdecAsDeleteReturnswfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable){ SwfdecAsScope *cur; guint i; SwfdecAsDeleteReturn ret; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), FALSE); g_return_val_if_fail (variable != NULL, FALSE); cur = frame->scope; for (i = 0; i < 256; i++) { ret = swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable); if (ret) return ret; if (cur->next == NULL) break; cur = cur->next; } if (i == 256) { swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded"); return FALSE; } g_assert (SWFDEC_IS_AS_FRAME (cur)); /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target set via SetTarget */ ret = swfdec_as_object_delete_variable (frame->target, variable); if (ret) return ret; /* 2) the global object */ return swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable);}/** * swfdec_as_frame_set_target: * @frame: a #SwfdecAsFrame * @target: the new object to use as target or %NULL to unset * * Sets the new target to be used in this @frame. The target is a legacy * Actionscript concept that is similar to "with". If you don't have to, * you shouldn't use this function. **/voidswfdec_as_frame_set_target (SwfdecAsFrame *frame, SwfdecAsObject *target){ g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); g_return_if_fail (target == NULL || SWFDEC_IS_AS_OBJECT (target)); if (target) { frame->target = target; } else { frame->target = frame->original_target; }}voidswfdec_as_frame_preload (SwfdecAsFrame *frame){ SwfdecAsObject *object, *args; guint i, current_reg = 1; SwfdecScript *script; SwfdecAsValue val; const SwfdecAsValue *cur; SwfdecAsContext *context; SwfdecAsStackIterator iter; g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); /* setup */ object = SWFDEC_AS_OBJECT (frame); context = object->context; script = frame->script; if (frame->script == NULL) goto out; /* create arguments and super object if necessary */ if ((script->flags & (SWFDEC_SCRIPT_PRELOAD_ARGS | SWFDEC_SCRIPT_SUPPRESS_ARGS)) != SWFDEC_SCRIPT_SUPPRESS_ARGS) { args = swfdec_as_array_new (context); if (!args) return; for (cur = swfdec_as_stack_iterator_init_arguments (&iter, frame); cur != NULL; cur = swfdec_as_stack_iterator_next (&iter)) { swfdec_as_array_push (SWFDEC_AS_ARRAY (args), cur); } } else { /* silence gcc */ args = NULL; } if ((script->flags & (SWFDEC_SCRIPT_PRELOAD_SUPER | SWFDEC_SCRIPT_SUPPRESS_SUPER)) != SWFDEC_SCRIPT_SUPPRESS_SUPER) { frame->super = swfdec_as_super_new (frame); } /* set the default variables (unless suppressed */ if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_THIS)) { if (frame->thisp) { SWFDEC_AS_VALUE_SET_OBJECT (&val, frame->thisp); } else { SWFDEC_AS_VALUE_SET_UNDEFINED (&val); } swfdec_as_object_set_variable (object, SWFDEC_AS_STR_this, &val); } if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_ARGS)) { SWFDEC_AS_VALUE_SET_OBJECT (&val, args); swfdec_as_object_set_variable (object, SWFDEC_AS_STR_arguments, &val); } if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_SUPER)) { if (frame->super) { SWFDEC_AS_VALUE_SET_OBJECT (&val, frame->super); } else { SWFDEC_AS_VALUE_SET_UNDEFINED (&val); } swfdec_as_object_set_variable (object, SWFDEC_AS_STR_super, &val); } /* set and preload argument variables */ SWFDEC_AS_VALUE_SET_UNDEFINED (&val); cur = swfdec_as_stack_iterator_init_arguments (&iter, frame); for (i = 0; i < script->n_arguments; i++) { if (cur == NULL) cur = &val; /* set this value at the right place */ if (script->arguments[i].preload) { if (script->arguments[i].preload < frame->n_registers) { frame->registers[script->arguments[i].preload] = *cur; } else { SWFDEC_ERROR ("trying to set %uth argument %s in nonexisting register %u", i, script->arguments[i].name, script->arguments[i].preload); } } else { const char *tmp = swfdec_as_context_get_string (context, script->arguments[i].name); swfdec_as_object_set_variable (object, tmp, cur); } /* get the next argument */ cur = swfdec_as_stack_iterator_next (&iter); } /* preload from flags */ if ((script->flags & (SWFDEC_SCRIPT_PRELOAD_THIS | SWFDEC_SCRIPT_SUPPRESS_THIS)) == SWFDEC_SCRIPT_PRELOAD_THIS && current_reg < script->n_registers) { if (frame->thisp) { SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], frame->thisp); } else { SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); } } if (script->flags & SWFDEC_SCRIPT_PRELOAD_ARGS && current_reg < script->n_registers) { SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], args); } if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER && current_reg < script->n_registers) { if (frame->super) { SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], frame->super); } else { SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); } } if (script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT && current_reg < script->n_registers) { SwfdecAsObject *obj; obj = swfdec_as_frame_find_variable (frame, SWFDEC_AS_STR__root); if (obj) { swfdec_as_object_get_variable (obj, SWFDEC_AS_STR__root, &frame->registers[current_reg]); } else { SWFDEC_WARNING ("no root to preload"); SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); } } if (script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT && current_reg < script->n_registers) { SwfdecAsObject *obj; obj = swfdec_as_frame_find_variable (frame, SWFDEC_AS_STR__parent); if (obj) { swfdec_as_object_get_variable (obj, SWFDEC_AS_STR__parent, &frame->registers[current_reg++]); } else { SWFDEC_WARNING ("no parent to preload"); SWFDEC_AS_VALUE_SET_UNDEFINED (&frame->registers[current_reg++]); } current_reg++; } if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL && current_reg < script->n_registers) { SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], context->global); }out: if (context->debugger) { SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger); if (klass->enter_frame) klass->enter_frame (context->debugger, context, frame); }}/** * swfdec_as_frame_check_scope: * @frame: a #SwfdecAsFrame * * Checks that the current scope of the given @frame is still correct. * If it is not, the current scope is popped and the next one is used. * If the **/voidswfdec_as_frame_check_scope (SwfdecAsFrame *frame){ SwfdecAsScope *frame_scope; g_return_if_fail (SWFDEC_IS_AS_FRAME (frame)); frame_scope = SWFDEC_AS_SCOPE (frame); while (frame->scope != frame_scope) { SwfdecAsScope *cur = frame->scope; if (frame->pc >= cur->startpc && frame->pc < cur->endpc) break; frame->scope = cur->next; }}/** * swfdec_as_frame_get_next: * @frame: a #SwfdecAsFrame * * Gets the next frame in the frame stack. The next frame is the frame that * will be executed after this @frame. * * Returns: the next #SwfdecAsFrame or %NULL if this is the bottommost frame. **/SwfdecAsFrame *swfdec_as_frame_get_next (SwfdecAsFrame *frame){ g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); return frame->next;}/** * swfdec_as_frame_get_function_name: * @frame: a #SwfdecAsFrame * * Gets the name of the function that is currently executing. This function is * intended for debugging purposes. * * Returns: a string. Do not free. **/const char *swfdec_as_frame_get_function_name (SwfdecAsFrame *frame){ g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); g_assert (frame->function_name); return frame->function_name;}/** * swfdec_as_frame_get_script: * @frame: a #SwfdecAsFrame * * Gets the script associated with the given @frame. If the frame references * a native function, there will be no script and this function returns %NULL. * * Returns: The script executed by this frame or %NULL **/SwfdecScript *swfdec_as_frame_get_script (SwfdecAsFrame *frame){ g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); return frame->script;}/** * swfdec_as_frame_get_this: * @frame: a #SwfdecAsFrame * * Gets the this object of the given @frame. If the frame has no this object, * %NULL is returned. * * Returns: The this object of the frame or %NULL if none. **/SwfdecAsObject *swfdec_as_frame_get_this (SwfdecAsFrame *frame){ g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); return frame->thisp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -