Пример #1
0
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
  TMS tm;
  Proto *p = ci_func(ci)->p;  /* calling function */
  int pc = currentpc(ci);  /* calling instruction index */
  Instruction i = p->code[pc];  /* calling instruction */
  switch (GET_OPCODE(i)) {
    case OP_CALL:
    case OP_TAILCALL:  /* get function name */
      return getobjname(p, pc, GETARG_A(i), name);
    case OP_TFORCALL: {  /* for iterator */
      *name = "for iterator";
       return "for iterator";
    }
    /* all other instructions can call only through metamethods */
    case OP_SELF:
    case OP_GETTABUP:
    case OP_GETTABLE: tm = TM_INDEX; break;
    case OP_SETTABUP:
    case OP_SETTABLE: tm = TM_NEWINDEX; break;
    case OP_EQ: tm = TM_EQ; break;
    case OP_ADD: tm = TM_ADD; break;
    case OP_SUB: tm = TM_SUB; break;
    case OP_MUL: tm = TM_MUL; break;
    case OP_DIV: tm = TM_DIV; break;
    case OP_IDIV: tm = TM_IDIV; break;
    case OP_MOD: tm = TM_MOD; break;
    case OP_POW: tm = TM_POW; break;
    case OP_UNM: tm = TM_UNM; break;
    case OP_LEN: tm = TM_LEN; break;
    case OP_LT: tm = TM_LT; break;
    case OP_LE: tm = TM_LE; break;
    case OP_CONCAT: tm = TM_CONCAT; break;
    default:
      return NULL;  /* else no useful name can be found */
  }
  *name = getstr(G(L)->tmname[tm]);
  return "metamethod";
}
Пример #2
0
void lua_printstack (FILE *f)
{
  int level = 0;
  lua_Object func;
  fprintf(f, "Active Stack:\n");
  while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT)
  {
    char *name;
    int currentline;
    fprintf(f, "\t");
    switch (*getobjname(func, &name))
    {
      case 'g':
        fprintf(f, "function %s", name);
        break;
      case 'f':
        fprintf(f, "fallback %s", name);
        break;
      default:
      {
        char *filename;
        int linedefined;
        lua_funcinfo(func, &filename, &linedefined);
        if (linedefined == 0)
          fprintf(f, "main of %s", filename);
        else if (linedefined < 0)
          fprintf(f, "%s", filename);
        else
          fprintf(f, "function (%s:%d)", filename, linedefined);
      }
    }
    if ((currentline = lua_currentline(func)) > 0)
      fprintf(f, "  at line %d", currentline);
    fprintf(f, "\n");
  }
}
Пример #3
0
static void vobj_read(struct GlobalVars *gv,struct LinkFile *lf,uint8_t *data)
{
  struct ObjectUnit *u;
  int bpb,bpt,nsecs,nsyms,i;
  struct vobj_symbol *vsymbols = NULL;

  if (lf->type == ID_LIBARCH) {  /* check ar-member for correct format */
    vobj_check_ar_type(fff[lf->format],lf->pathname,data);
  }
  p = data + 5;  /* skip ID and endianess */
  bpb = (int)read_number();  /* bits per byte */
  if (bpb != 8) {
    /* bits per byte are not supported */
    error(113,lf->pathname,fff[lf->format]->tname,bpb);
  }
  bpt = (int)read_number();  /* bytes per taddr */
  if (bpt > sizeof(taddr)) {
    /* n bytes per target-address are not supported */
    error(114,lf->pathname,fff[lf->format]->tname,bpt);
  }
  skip_string();  /* skip cpu-string */

  u = create_objunit(gv,lf,lf->objname);
  nsecs = (int)read_number();  /* number of sections */
  nsyms = (int)read_number();  /* number of symbols */

  if (nsyms) {
    vsymbols = alloc(nsyms * sizeof(struct vobj_symbol));
    for (i=0; i<nsyms; i++)
      read_symbol(&vsymbols[i]);
  }

  for (i=1; i<=nsecs; i++)
    read_section(gv,u,(uint32_t)i,vsymbols,nsyms);

  /* add relocatable and absolute symbols, ignore unknown symbol-refs */
  for (i=0; i<nsyms; i++) {
    struct vobj_symbol *vs = &vsymbols[i];
    struct Section *s = NULL;
    uint8_t type,bind,info;

    if (vs->flags & WEAK)
      bind = SYMB_WEAK;
    else if (vs->flags & EXPORT)
      bind = SYMB_GLOBAL;
    else
      bind = SYMB_LOCAL;

    if (vs->flags & COMMON) {
      type = SYM_COMMON;
      s = common_section(gv,u);
    }
    else if (vs->type == EXPRESSION) {
      type = SYM_ABS;
      s = abs_section(u);
    }
    else if (vs->type == LABSYM) {
      type = SYM_RELOC;
      if (!(s = find_sect_id(u,vs->sec))) {
        /* a section with this index doesn't exist! */
        error(53,lf->pathname,vs->name,lf->objname,vs->sec);
      }
    }
    else if (vs->type == IMPORT) {
      type = 0;  /* ignore unknown symbols */
    }
    else {
      /* illegal symbol type */
      error(116,getobjname(u),fff[lf->format]->tname,
            vs->type,vs->name,lf->objname);
      type = 0;
    }

    switch (TYPE(vs)) {
      case TYPE_UNKNOWN: info = SYMI_NOTYPE; break;
      case TYPE_OBJECT: info = SYMI_OBJECT; break;
      case TYPE_FUNCTION: info = SYMI_FUNC; break;
      case TYPE_SECTION: type = 0; break;  /* ignore SECTION symbols */
      case TYPE_FILE: info = SYMI_FILE; break;
      default:
        error(54,lf->pathname,TYPE(vs),vs->name,lf->objname);
        type = 0;
        break;
    }

    if (type) {
      if (bind == SYMB_LOCAL)
        addlocsymbol(gv,s,vs->name,NULL,(lword)vs->val,type,0,info,vs->size);
      else
        addsymbol(gv,s,vs->name,NULL,(lword)vs->val,
                  type,0,info,bind,vs->size,TRUE);
    }
  }
  if (nsyms)
    free(vsymbols);

  add_objunit(gv,u,TRUE);  /* add object unit and fix relocations */
}
Пример #4
0
static void read_section(struct GlobalVars *gv,struct ObjectUnit *u,
                         uint32_t index,struct vobj_symbol *vsyms,int nsyms)
{
  struct Section *s;
  lword dsize,fsize;
  int nrelocs;
  uint8_t type = ST_DATA;
  uint8_t prot = SP_READ;
  uint8_t flags = 0;
  uint8_t align,*data;
  char *attr;
  char *name = p;
  struct Reloc *last_reloc;
  int last_sym = -1;
  lword last_offs;
  uint16_t last_bpos = INVALID;

  skip_string();  /* section name */
  for (attr=p; *attr; attr++) {
    switch (tolower((unsigned char)*attr)) {
      case 'w': prot |= SP_WRITE; break;
      case 'x': prot |= SP_EXEC; break;
      case 'c': type = ST_CODE; break;
      case 'd': type = ST_DATA; break;
      case 'u': type = ST_UDATA; flags |= SF_UNINITIALIZED; break;
      case 'a': flags |= SF_ALLOC;
    }
  }
  skip_string();
  read_number();                  /* ignore flags */
  align = (uint8_t)lshiftcnt(read_number());
  dsize = read_number();          /* total size of section */
  nrelocs = (int)read_number();   /* number of relocation entries */
  fsize = read_number();          /* size in file, without 0-bytes */

  if (type == ST_UDATA) {
    data = NULL;
  }
  else if (dsize > fsize) {       /* recreate 0-bytes at end of section */
    data = alloczero((size_t)dsize);
    memcpy(data,p,(size_t)fsize);
  }
  else
    data = p;

  /* create and add section */
  p += fsize;
  s = add_section(u,name,data,(unsigned long)dsize,type,flags,prot,align,0);
  s->id = index;

  /* create relocations and unkown symbol references for this section */
  for (last_reloc=NULL,last_offs=-1; nrelocs>0; nrelocs--) {
    struct Reloc *r;
    char *xrefname = NULL;
    lword offs,mask,addend;
    uint16_t bpos,bsiz;
    uint8_t flags;
    int sym_idx;

    /* read one relocation entry */
    type = (uint8_t)read_number();
    offs = read_number();
    bpos = (uint16_t)read_number();
    bsiz = (uint16_t)read_number();
    mask = read_number();
    addend = read_number();
    sym_idx = (int)read_number() - 1;  /* symbol index */
    flags = 0;

    if (type>R_NONE && type<=LAST_STANDARD_RELOC &&
        offs>=0 && bsiz<=(sizeof(lword)<<3) &&
        sym_idx>=0 && sym_idx<nsyms) {
      if (vsyms[sym_idx].type == LABSYM) {
        xrefname = NULL;
        index = vsyms[sym_idx].sec;
      }
      else if (vsyms[sym_idx].type == IMPORT) {
        xrefname = vsyms[sym_idx].name;
        if (vsyms[sym_idx].flags & WEAK)
          flags |= RELF_WEAK;  /* undefined weak symbol */
        index = 0;
      }
      else {
        /* VOBJ relocation not supported */
        error(115,getobjname(u),fff[u->lnkfile->format]->tname,
              (int)type,(lword)offs,(int)bpos,(int)bsiz,(lword)mask,
              vsyms[sym_idx].name,(int)vsyms[sym_idx].type);
      }

      if (sym_idx==last_sym && offs==last_offs && bpos==last_bpos &&
          last_reloc!=NULL) {
        r = last_reloc;
      }
      else {
        r = newreloc(gv,s,xrefname,NULL,index,(unsigned long)offs,type,addend);
        r->flags |= flags;
        last_reloc = r;
        last_offs = offs;
        last_bpos = bpos;
        last_sym = sym_idx;
      }

      addreloc(s,r,bpos,bsiz,mask);

      /* make sure that section reflects the addend for other formats */
      writesection(gv,data+(uint32_t)offs,r,addend);
    }

    else if (type != R_NONE) {
      /* VOBJ relocation not supported */
      error(115,getobjname(u),fff[u->lnkfile->format]->tname,
            (int)type,(lword)offs,(int)bpos,(int)bsiz,(lword)mask,
            (sym_idx>=0&&sym_idx<nsyms) ? vsyms[sym_idx].name : "?",
            (sym_idx>=0&&sym_idx<nsyms) ? (int)vsyms[sym_idx].type : 0);
    }
  }
}
Пример #5
0
void MCStack::effectrect(const MCRectangle& p_area, Boolean& r_abort)
{
	// Get the list of effects.
	MCEffectList *t_effects = MCcur_effects;
	MCcur_effects = NULL;

	// If the window isn't opened or hasn't been attached (plugin) or if we have no
	// snapshot to use, this is a no-op.
	if (!opened || !haswindow() || m_snapshot == nil)
	{
		while(t_effects != NULL)
		{
			MCEffectList *t_effect;
			t_effect = t_effects;
			t_effects = t_effects -> next;
			delete t_effect;
		}
		return;
	}

	// Mark the stack as being in an effect.
	state |= CS_EFFECT;

	// Lock messages while the effect is happening.
	Boolean t_old_lockmessages;
	t_old_lockmessages = MClockmessages;
	MClockmessages = True;

	// Calculate the area of interest.
	MCRectangle t_effect_area;
	t_effect_area = curcard -> getrect();
	t_effect_area . y = getscroll();
	t_effect_area . height -= t_effect_area . y;
	t_effect_area = MCU_intersect_rect(t_effect_area, p_area);
	
	// IM-2013-08-21: [[ ResIndependence ]] Scale effect area to device coords
	// Align snapshot rect to device pixels
	// IM-2013-09-30: [[ FullscreenMode ]] Use stack transform to get device coords
	MCGAffineTransform t_transform;
	t_transform = getdevicetransform();
	
    // MW-2013-10-29: [[ Bug 11330 ]] Make sure the effect area is cropped to the visible
    //   area.
    t_effect_area = MCRectangleGetTransformedBounds(t_effect_area, getviewtransform());
    t_effect_area = MCU_intersect_rect(t_effect_area, MCU_make_rect(0, 0, view_getrect() . width, view_getrect() . height));
	
	// IM-2014-01-24: [[ HiDPI ]] scale effect region to backing surface coords
	MCGFloat t_scale;
	t_scale = view_getbackingscale();
	
    MCRectangle t_device_rect, t_user_rect;
	t_device_rect = MCRectangleGetScaledBounds(t_effect_area, t_scale);
	t_user_rect = MCRectangleGetTransformedBounds(t_device_rect, MCGAffineTransformInvert(t_transform));
	
	// IM-2013-08-29: [[ RefactorGraphics ]] get device height for CoreImage effects
	// IM-2013-09-30: [[ FullscreenMode ]] Use view rect to get device height
	uint32_t t_device_height;
	t_device_height = floor(view_getrect().height * t_scale);
	
	// Make a region of the effect area
	// IM-2013-08-29: [[ ResIndependence ]] scale effect region to device coords
	MCRegionRef t_effect_region;
	t_effect_region = nil;
	/* UNCHECKED */ MCRegionCreate(t_effect_region);
	/* UNCHECKED */ MCRegionSetRect(t_effect_region, t_effect_area);
	
#ifndef FEATURE_PLATFORM_PLAYER
#if defined(FEATURE_QUICKTIME)
	// MW-2010-07-07: Make sure QT is only loaded if we actually are doing an effect
	if (t_effects != nil)
		if (!MCdontuseQTeffects)
			if (!MCtemplateplayer -> isQTinitted())
				MCtemplateplayer -> initqt();
#endif	
#endif

	// Lock the screen to prevent any updates occuring until we want them.
	MCRedrawLockScreen();

	// By default, we have not aborted.
	r_abort = False;
	
	MCGImageRef t_initial_image;
	t_initial_image = MCGImageRetain(m_snapshot);
	
	while(t_effects != nil)
	{
		uint32_t t_duration;
		t_duration = MCU_max(1, MCeffectrate / (t_effects -> speed - VE_VERY));
		if (t_effects -> type == VE_DISSOLVE)
			t_duration *= 2;
		
		uint32_t t_delta;
		t_delta = 0;
		
		// Create surface at effect_area size.
		// Render into surface based on t_effects -> image
		MCGImageRef t_final_image = nil;
		
		// If this isn't a plain effect, then we must fetch first and last images.
		if (t_effects -> type != VE_PLAIN)
		{
			// Render the final image.
			MCGContextRef t_context = nil;
			
			// IM-2014-05-20: [[ GraphicsPerformance ]] Create opaque context for snapshot
			/* UNCHECKED */ MCGContextCreate(t_device_rect.width, t_device_rect.height, false, t_context);
			
			MCGContextTranslateCTM(t_context, -t_device_rect.x, -t_device_rect.y);
			
			// IM-2013-10-03: [[ FullscreenMode ]] Apply device transform to context
			MCGContextConcatCTM(t_context, t_transform);
			
			// Configure the context.
			MCGContextClipToRect(t_context, MCRectangleToMCGRectangle(t_user_rect));
			
			// Render an appropriate image
			switch(t_effects -> image)
			{
				case VE_INVERSE:
					{
						MCContext *t_old_context = nil;
						/* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context);
						curcard->draw(t_old_context, t_user_rect, false);
						delete t_old_context;
						
						MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0);
						MCGContextSetBlendMode(t_context, kMCGBlendModeDifference);
						MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect));
						MCGContextFill(t_context);
					}
					break;
					
				case VE_BLACK:
					MCGContextSetFillRGBAColor(t_context, 0.0, 0.0, 0.0, 1.0);
					MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect));
					MCGContextFill(t_context);
					break;
					
				case VE_WHITE:
					MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0);
					MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect));
					MCGContextFill(t_context);
					break;
					
				case VE_GRAY:
					MCGContextSetFillRGBAColor(t_context, 0.5, 0.5, 0.5, 1.0);
					MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect));
					MCGContextFill(t_context);
					break;
					
				default:
				{
					MCContext *t_old_context = nil;
					/* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context);
					curcard->draw(t_old_context, t_user_rect, false);
					delete t_old_context;
				}
			}
			
			/* UNCHECKED */ MCGContextCopyImage(t_context, t_final_image);
			MCGContextRelease(t_context);
		}
		
		MCStackEffectContext t_context;
		t_context.delta = t_delta;
		t_context.duration = t_duration;
		t_context.effect = t_effects;
		t_context.effect_area = t_device_rect;
		t_context.initial_image = t_initial_image;
		t_context.final_image = t_final_image;
		
		// MW-2011-10-20: [[ Bug 9824 ]] Make sure dst point is correct.
		// Initialize the destination with the start image.
		view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderInitial, &t_context);
		
		// If there is a sound, then start playing it.
		if (t_effects -> sound != NULL)
		{
			MCAudioClip *acptr;
            MCNewAutoNameRef t_sound;
            /* UNCHECKED */ MCNameCreate(t_effects->sound, &t_sound);
			if ((acptr = (MCAudioClip *)getobjname(CT_AUDIO_CLIP, *t_sound)) == NULL)
			{
				IO_handle stream;
				if ((stream = MCS_open(t_effects->sound, kMCOpenFileModeRead, True, False, 0)) != NULL)
				{
					acptr = new MCAudioClip;
					acptr->setdisposable();
					if (!acptr->import(t_effects->sound, stream))
					{
						delete acptr;
						acptr = NULL;
					}
					MCS_close(stream);
				}
			}
			
			if (acptr != NULL)
			{
				MCU_play_stop();
				MCacptr = acptr;
				MCU_play();
#ifndef FEATURE_PLATFORM_AUDIO
				if (MCacptr != NULL)
					MCscreen->addtimer(MCacptr, MCM_internal, PLAY_RATE);
#endif
			}
			
			if (MCscreen->wait((real8)MCsyncrate / 1000.0, False, True))
			{
				r_abort = True;
				break;
			}
		}
		
		// Initialize CoreImage of QTEffects if needed.
		if (t_effects -> type != VE_PLAIN)
		{
            MCAutoPointer<char> t_name;
            /* UNCHECKED */ MCStringConvertToCString(t_effects -> name, &t_name);
#ifdef _MAC_DESKTOP
			// IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for CI effects
			if (t_effects -> type == VE_UNDEFINED && MCCoreImageEffectBegin(*t_name, t_initial_image, t_final_image, t_device_rect, t_device_height, t_effects -> arguments))
				t_effects -> type = VE_CIEFFECT;
			else
#endif
#ifdef FEATURE_QUICKTIME_EFFECTS
				// IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for QT effects
				if (t_effects -> type == VE_UNDEFINED && MCQTEffectBegin(t_effects -> type, *t_name, t_effects -> direction, t_initial_image, t_final_image, t_device_rect))
					t_effects -> type = VE_QTEFFECT;
#else
				;
#endif
		}
		
		// Run effect
		// Now perform the effect loop, but only if there is something to do.
		if (t_effects -> type != VE_PLAIN || old_blendlevel != blendlevel)
		{
			// Calculate timing parameters.
			double t_start_time;
			t_start_time = 0.0;
			
			for(;;)
			{
				t_context.delta = t_delta;
				
				Boolean t_drawn = False;
				view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderEffect, &t_context);
				
				// Now redraw the window with the new image.
//				if (t_drawn)
				{
					MCscreen -> sync(getw());
				}
				
				// Update the window's blendlevel (if needed)
				if (old_blendlevel != blendlevel)
				{
					float t_fraction = float(t_delta) / t_duration;
					setopacity(uint1((old_blendlevel * 255 + (float(blendlevel) - old_blendlevel) * 255 * t_fraction) / 100));
				}
				
				// If the start time is zero, then start counting from here.
				if (t_start_time == 0.0)
					t_start_time = MCS_time();
				
				// If we've reached the end of the transition, we are done.
				if (t_delta == t_duration)
				{
#ifdef _ANDROID_MOBILE
					// MW-2011-12-12: [[ Bug 9907 ]] Make sure we let the screen sync at this point
					MCscreen -> wait(0.01, False, False);
#endif
					break;
				}
				
				// Get the time now.
				double t_now;
				t_now = MCS_time();
				
				// Compute the new delta value.
				uint32_t t_new_delta;
				t_new_delta = (uint32_t)ceil((t_now - t_start_time) * 1000.0);
				
				// If the new value is same as the old, then advance one step.
				if (t_new_delta == t_delta)
					t_delta = t_new_delta + 1;
				else
					t_delta = t_new_delta;
				
				// If the new delta is beyond the end point, set it to the end.
				if (t_delta > t_duration)
					t_delta = t_duration;
				
				// Wait until the next boundary, making sure we break for no reason
				// other than abort.
				if (MCscreen -> wait((t_start_time + (t_delta / 1000.0)) - t_now, False, False))
					r_abort = True;
				
				// If we aborted, we render the final step and are thus done.
				if (r_abort)
					t_delta = t_duration;
			}
		}		
#ifdef _MAC_DESKTOP
		if (t_effects -> type == VE_CIEFFECT)
			MCCoreImageEffectEnd();
		else
#endif
#ifdef FEATURE_QUICKTIME_EFFECTS
			if (t_effects -> type == VE_QTEFFECT)
				MCQTEffectEnd();
#endif
		
		// Free initial surface.
		MCGImageRelease(t_initial_image);
		
		// initial surface becomes final surface.
		t_initial_image = t_final_image;
		t_final_image = nil;
		
		// Move to the next effect.
		MCEffectList *t_current_effect;
		t_current_effect = t_effects;
		t_effects = t_effects -> next;
		delete t_current_effect;
	}

	// Make sure the pixmaps are freed and any dangling effects
	// are cleaned up.
	if (t_effects != NULL)
	{
		/* OVERHAUL - REVISIT: error cleanup needs revised */
		MCGImageRelease(t_initial_image);
//		MCGSurfaceRelease(t_final_image);

		while(t_effects != NULL)
		{
			MCEffectList *t_current_effect;
			t_current_effect = t_effects;
			t_effects = t_effects -> next;
			delete t_current_effect;
		}
	}

	MCRegionDestroy(t_effect_region);
	
	MCGImageRelease(m_snapshot);
	m_snapshot = nil;
	
	m_snapshot = t_initial_image;
	
	// Unlock the screen.
	MCRedrawUnlockScreen();
	
	// Unlock messages.
	MClockmessages = t_old_lockmessages;

	// Turn off effect mode.
	state &= ~CS_EFFECT;
	
	// The stack's blendlevel is now the new one.
	old_blendlevel = blendlevel;
	
	// Finally, mark the affected area of the stack for a redraw.
	dirtyrect(p_area);
}