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"; }
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"); } }
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 */ }
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); } } }
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); }