📄 ttinterp.c
字号:
/***************************************************************************//* *//* ttinterp.c *//* *//* TrueType bytecode intepreter (body). *//* *//* Copyright 1996-1999 by *//* David Turner, Robert Wilhelm, and Werner Lemberg. *//* *//* This file is part of the FreeType project, and may only be used *//* modified and distributed under the terms of the FreeType project *//* license, LICENSE.TXT. By continuing to use, modify, or distribute *//* this file you indicate that you have read the license and *//* understand and accept it fully. *//* *//***************************************************************************/#include <ftdebug.h>#include <ftsystem.h>#include <ftcalc.h>#include <ttobjs.h>#include <ttinterp.h>#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER#define TT_MULFIX FT_MulFix#define TT_MULDIV FT_MulDiv#define TT_INT64 FT_Int64/* required by the tracing mode */#undef FT_COMPONENT#define FT_COMPONENT trace_ttinterp#undef NO_APPLE_PATENT#define APPLE_THRESHOLD 0x4000000 /*************************************************************************/ /* */ /* In order to detect infinite loops in the code, we set-up a counter */ /* within the run loop. a single stroke of interpretation is now limited */ /* to a maximum number of opcodes defined below. */ /* */#define MAX_RUNNABLE_OPCODES 1000000 /*************************************************************************/ /* */ /* There are two kinds of implementations: */ /* */ /* a. static implementation: */ /* */ /* The current execution context is a static variable, which fields */ /* are accessed directly by the interpreter during execution. The */ /* context is named `cur'. */ /* */ /* This version is non-reentrant, of course. */ /* */ /* b. indirect implementation: */ /* */ /* The current execution context is passed to _each_ function as its */ /* first argument, and each field is thus accessed indirectly. */ /* */ /* This version is fully re-entrant. */ /* */ /* The idea is that an indirect implementation may be slower to execute */ /* on low-end processors that are used in some systems (like 386s or */ /* even 486s). */ /* */ /* As a consequence, the indirect implementation is now the default, as */ /* its performance costs can be considered negligible in our context. */ /* Note, however, that we kept the same source with macros because: */ /* */ /* - The code is kept very close in design to the Pascal code used for */ /* development. */ /* */ /* - It's much more readable that way! */ /* */ /* - It's still open to experimentation and tuning. */ /* */ /*************************************************************************/#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */#define CUR (*exc) /* see ttobjs.h */#else /* static implementation */#define CUR cur static TT_ExecContextRec cur; /* static exec. context variable */ /* apparently, we have a _lot_ of direct indexing when accessing */ /* the static `cur', which makes the code bigger (due to all the */ /* four bytes addresses). */#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ /*************************************************************************/ /* */ /* Most of FreeType builds don't use engine compensations. We thus */ /* introduce a macro, FT_CONFIG_OPTION_INTERPRETER_QUICK, which controls */ /* the use of these values. */ /* */#define INS_ARG EXEC_OP_ TT_Long* args /* see ttobjs.h for EXEC_OP_ */ /*************************************************************************/ /* */ /* This macro is used whenever `exec' is unused in a function, to avoid */ /* stupid warnings from pedantic compilers. */ /* */#define UNUSED_EXEC (void)CUR /*************************************************************************/ /* */ /* This macro is used whenever `args' is unused in a function, to avoid */ /* stupid warnings from pedantic compilers. */ /* */#define UNUSED_ARG UNUSED_EXEC; (void)args; /*************************************************************************/ /* */ /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ /* increase readabiltyof the code. */ /* */ /*************************************************************************/#define SKIP_Code() \ SkipCode( EXEC_ARG )#define GET_ShortIns() \ GetShortIns( EXEC_ARG )#define NORMalize( x, y, v ) \ Normalize( EXEC_ARG_ x, y, v )#define SET_SuperRound( scale, flags ) \ SetSuperRound( EXEC_ARG_ scale, flags )#define ROUND_None( d, c ) \ Round_None( EXEC_ARG_ d, c )#define INS_Goto_CodeRange( range, ip ) \ Ins_Goto_CodeRange( EXEC_ARG_ range, ip )#define CUR_Func_project( x, y ) \ CUR.func_project( EXEC_ARG_ x, y )#define CUR_Func_move( z, p, d ) \ CUR.func_move( EXEC_ARG_ z, p, d )#define CUR_Func_dualproj( x, y ) \ CUR.func_dualproj( EXEC_ARG_ x, y )#define CUR_Func_freeProj( x, y ) \ CUR.func_freeProj( EXEC_ARG_ x, y )#define CUR_Func_round( d, c ) \ CUR.func_round( EXEC_ARG_ d, c )#define CUR_Func_read_cvt( index ) \ CUR.func_read_cvt( EXEC_ARG_ index )#define CUR_Func_write_cvt( index, val ) \ CUR.func_write_cvt( EXEC_ARG_ index, val )#define CUR_Func_move_cvt( index, val ) \ CUR.func_move_cvt( EXEC_ARG_ index, val )#define CURRENT_Ratio() \ Current_Ratio( EXEC_ARG )#define CURRENT_Ppem() \ Current_Ppem( EXEC_ARG )#define CUR_Ppem() \ Cur_PPEM( EXEC_ARG )#define CALC_Length() \ Calc_Length( EXEC_ARG )#define INS_SxVTL( a, b, c, d ) \ Ins_SxVTL( EXEC_ARG_ a, b, c, d )#define COMPUTE_Funcs() \ Compute_Funcs( EXEC_ARG )#define COMPUTE_Round( a ) \ Compute_Round( EXEC_ARG_ a )#define COMPUTE_Point_Displacement( a, b, c, d ) \ Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )#define MOVE_Zp2_Point( a, b, c, t ) \ Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) /*************************************************************************/ /* */ /* Instruction dispatch function, as used by the interpreter. */ /* */ typedef void (*TInstruction_Function)( INS_ARG ); /*************************************************************************/ /* */ /* A simple bounds-checking macro. */ /* */#define BOUNDS( x, n ) ((TT_UInt)(x) >= (TT_UInt)(n))#undef SUCCESS#define SUCCESS 0#undef FAILURE#define FAILURE 1 /*************************************************************************/ /* */ /* CODERANGE FUNCTIONS */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* TT_Goto_CodeRange */ /* */ /* <Description> */ /* Switches to a new code range (updates the code related elements in */ /* `exec', and `IP'). */ /* */ /* <Input> */ /* range :: The new execution code range. */ /* IP :: The new IP in the new code range. */ /* */ /* <InOut> */ /* exec :: The target execution context. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ EXPORT_FUNC TT_Error TT_Goto_CodeRange( TT_ExecContext exec, TT_Int range, TT_Long IP ) { TT_CodeRange* coderange; FT_Assert( range >= 1 && range <= 3 ); coderange = &exec->codeRangeTable[range - 1]; FT_Assert( coderange->base != NULL ); /* NOTE: Because the last instruction of a program may be a CALL */ /* which will return to the first byte *after* the code */ /* range, we test for IP <= Size, instead of IP < Size. */ /* */ FT_Assert( (TT_ULong)IP <= coderange->size ); exec->code = coderange->base; exec->codeSize = coderange->size; exec->IP = IP; exec->curRange = range; return TT_Err_Ok; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Set_CodeRange */ /* */ /* <Description> */ /* Sets a code range. */ /* */ /* <Input> */ /* range :: The code range index. */ /* base :: The new code base. */ /* length :: The range size in bytes. */ /* */ /* <InOut> */ /* exec :: The target execution context. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ EXPORT_FUNC TT_Error TT_Set_CodeRange( TT_ExecContext exec, TT_Int range, void* base, TT_Long length ) { FT_Assert( range >= 1 && range <= 3 ); exec->codeRangeTable[range - 1].base = (TT_Byte*)base; exec->codeRangeTable[range - 1].size = length; return TT_Err_Ok; } /*************************************************************************/ /* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -