ret nodes emits at least one
+ * branch.
+ */
+ edges += nodes - 1 - ctx->m_retnum;
+
+ // allocate memory for graph structure
+ void *mem_graph = vf_palloc( ctx->m_pool, sizeof( vf_Graph ) );
+ // for graph creation use pre-calculated numbers
+ vf_Graph *graph = new( mem_graph ) vf_Graph( nodes, edges, ctx );
+ ctx->m_graph = graph;
+
+ /**
+ * Create nodes.
+ */
+ graph->NewNode( VF_NODE_START_ENTRY );
// create handler nodes
unsigned node_index;
- unsigned short handler_count =
- method_get_exc_handler_number( ctex->m_method );
for( node_index = 1; node_index <= ( unsigned )handler_count;
node_index++ ) {
- graph->NewNode( VF_TYPE_NODE_HANDLER, 1 );
+ graph->NewNode( VF_NODE_HANDLER );
}
- /**
- * Create code range nodes. New node correspond to the subsequent
- * basic blocks of instructions.
- * Note: code range nodes follow after the last handler node.
- */
- // adding a basic block which starts
- for( unsigned bb_start = 0; bb_start < ctex->m_codeNum; node_index++ ) {
+ // create code range nodes right after the last handler node
+ // a new node correspond to a subsequent basic block of instructions
+ for( vf_InstrHandle bb_start = ctx->m_instr;
+ bb_start < ctx->m_last_instr; node_index++ ) {
// find a basic block end
- unsigned next_bb_start = bb_start + 1;
- while( ( next_bb_start < ctex->m_codeNum )
- && ( !ctex->m_code[next_bb_start].m_basic_block_start ) ) {
+ vf_InstrHandle next_bb_start = bb_start + 1;
+ while( ( next_bb_start < ctx->m_last_instr )
+ && ( !next_bb_start->m_is_bb_start ) ) {
next_bb_start++;
}
- int stack = vf_get_node_stack_depth( &ctex->m_code[bb_start],
- &ctex->m_code[next_bb_start -
- 1] );
- graph->NewNode( bb_start, next_bb_start - 1, stack );
- code2node[bb_start] = node_index;
+ ( (vf_Instr*)bb_start )->m_node =
+ graph->NewNode( bb_start, next_bb_start - 1 );
bb_start = next_bb_start;
}
// create exit-entry node
- graph->NewNode( VF_TYPE_NODE_END_ENTRY, 0 );
+ graph->AddEndNode();
unsigned node_num = node_index + 1;
- assert( ctex->m_nodeNum == node_num );
+ assert( 0 == graph->HasMoreNodeSpace() );
/**
- * Create edges
+ * Create edges.
*/
+ vf_Node *node = (vf_Node*)graph->GetNode( handler_count + 1 );
- // from start-entry node to the first code node
- node_index = handler_count + 1;
- graph->NewEdge( 0, node_index );
+ // from start-entry node to the first code range node
+ graph->NewEdge( (vf_Node*)graph->GetStartNode(), node );
// create code range edges
- for( ; node_index < node_num - 1; node_index++ ) {
- vf_Code_t *code =
- &ctex->m_code[graph->GetNodeLastInstr( node_index )];
+ for( ; VF_NODE_CODE_RANGE == node->m_type; node++ ) {
+ vf_InstrHandle instr = node->m_end;
// set control flow edges
- if( code->m_offcount ) {
- for( unsigned count = 0; count < code->m_offcount; count++ ) {
- int offset = vf_get_code_branch( code, count );
- unsigned node = code2node[ctex->m_bc[offset].m_instr - 1];
+ if( instr->m_offcount ) {
+ for( unsigned count = 0; count < instr->m_offcount; count++ ) {
+ int offset = vf_get_instr_branch( instr, count );
+ vf_Node *next_node =
+ (vf_Node*)graph->GetNodeFromBytecodeIndex( offset );
assert( node );
- graph->NewEdge( node_index, node );
- if( node < node_index ) {
+ graph->NewEdge( node, next_node );
+ if( next_node < node ) {
// node has a backward branch, thus any
// object on the stack should be initialized
- graph->SetNodeInitFlag( node, true );
+ node->m_initialized = true;
}
}
- } else if( code->m_type ) {
- // FIXME compatibility issue - no need to
- // have these branches for VF_TYPE_INSTR_SUBROUTINE
- graph->NewEdge( node_index, node_num - 1 );
- } else if( node_index + 1 < node_num ) {
- graph->NewEdge( node_index, node_index + 1 );
+ } else if( VF_INSTR_RETURN == instr->m_type
+ || VF_INSTR_THROW == instr->m_type ) {
+ graph->NewEdge( node, (vf_Node*)graph->GetEndNode() );
+ } else if( VF_INSTR_RET == instr->m_type ) {
+ // no edges from ret
+ } else if( VF_NODE_CODE_RANGE == ( node + 1 )->m_type ) {
+ graph->NewEdge( node, node + 1 );
} else {
- VERIFY_REPORT_METHOD( ctex, "Falling off the end of the code" );
+ VF_REPORT( ctx, "Falling off the end of the code" );
return VER_ErrorBranch;
}
}
+ assert( VF_NODE_END_ENTRY == node->m_type );
// create OUT map vectors for handler nodes
- unsigned char *start_bc = method_get_bytecode( ctex->m_method );
- unsigned bytecode_len = method_get_code_length( ctex->m_method );
+ unsigned char *start_bc = method_get_bytecode( ctx->m_method );
for( unsigned short handler_index = 0;
handler_index < handler_count; handler_index++ ) {
unsigned short start_pc, end_pc, handler_pc, handler_cp_index;
- method_get_exc_handler_info( ctex->m_method,
+ method_get_exc_handler_info( ctx->m_method,
handler_index, &start_pc, &end_pc,
&handler_pc, &handler_cp_index );
- vf_ValidType_t *type = NULL;
+ vf_ValidType *type = NULL;
if( handler_cp_index ) {
- const char *name = vf_get_cp_class_name( ctex->m_class,
+ const char *name = vf_get_cp_class_name( ctx->m_class,
handler_cp_index );
assert( name );
- type = vf_create_class_valid_type( name, ctex );
+ type = vf_create_class_valid_type( name, ctx );
// set restriction for handler class
- if( ctex->m_vtype.m_throwable->string[0] != type->string[0] ) {
- ctex->m_type->SetRestriction( ctex->m_vtype.m_throwable->
- string[0], type->string[0], 0,
- VF_CHECK_SUPER );
+ if( ctx->m_vtype.m_throwable->string[0] != type->string[0] ) {
+ ctx->m_type->SetRestriction( ctx->m_vtype.m_throwable->
+ string[0], type->string[0], 0,
+ VF_CHECK_SUPER );
}
}
@@ -687,163 +482,260 @@ vf_create_graph( vf_Context_t * ctex )
* created with during the process of merge.
*/
vf_MapVector *p_outvector = (vf_MapVector*)
- graph->GetNodeOutVector( handler_index + 1 );
+ &graph->GetNode( handler_index + 1 )->m_outmap;
p_outvector->m_stack =
- (vf_MapEntry_t*) graph->AllocMemory( sizeof( vf_MapEntry_t ) );
+ (vf_MapEntry*)graph->AllocMemory( sizeof( vf_MapEntry ) *
+ ctx->m_maxstack );
p_outvector->m_depth = 1;
vf_set_vector_stack_entry_ref( p_outvector->m_stack, 0, type );
// outcoming handler edge
- graph->NewEdge( handler_index + 1,
- code2node[ctex->m_bc[handler_pc].m_instr - 1] );
+ vf_Node *handler_node =
+ (vf_Node*)graph->GetNode( handler_index + 1 );
+ graph->NewEdge( handler_node,
+ (vf_Node*)graph->
+ GetNodeFromBytecodeIndex( handler_pc ) );
// node range start
- node_index = code2node[ctex->m_bc[start_pc].m_instr - 1];
+ node = (vf_Node*)graph->GetNodeFromBytecodeIndex( start_pc );
- unsigned last_node = ( end_pc == bytecode_len )
- ? node_num - 1 : code2node[ctex->m_bc[end_pc].m_instr - 1];
+ vf_NodeHandle last_node = ( end_pc == ctx->m_len )
+ ? graph->GetEndNode()
+ : graph->GetNodeFromBytecodeIndex( end_pc );
- for( ; node_index < last_node; node_index++ ) {
+ for( ; node < last_node; node++ ) {
// node is protected by exception handler, thus the
// reference in local variables have to be initialized
- graph->SetNodeInitFlag( node_index, true );
- graph->NewEdge( node_index, handler_index + 1 );
+ node->m_initialized = true;
+ graph->NewEdge( node, handler_node );
}
}
// one edge is reserved
- assert( graph->GetEdgeCount() == ctex->m_edgeNum );
+ assert( 0 == graph->HasMoreEdgeSpace() );
-#if _VERIFY_DEBUG
- if( ctex->m_dump.m_graph ) {
- graph->DumpGraph( ctex );
- }
- if( ctex->m_dump.m_dot_graph ) {
- graph->DumpDotGraph( ctex );
- }
-#endif // _VERIFY_DEBUG
+ VF_DUMP( DUMP_GRAPH, graph->DumpGraph() );
+ VF_DUMP( DUMP_DOT, graph->DumpDotGraph() );
return VER_OK;
} // vf_create_graph
/************************************************************
- *************** Graph Stack Deep Analysis ******************
+ *************** Graph Stack Depth Analysis *****************
************************************************************/
-
/**
- * Function evaluates stack depth of graph code range node.
+ * Checks stack depth of a node.
*/
-static int
-vf_get_node_stack_depth( vf_Code_t * start, // beginning instruction
- vf_Code_t * end ) // ending instruction
-{
- assert( start <= end );
+vf_Result
+vf_check_node_stack_depth( vf_Node *node, // a graph node
+ unsigned &depth, // initial stack depth
+ vf_Context *ctx ) // verification context
+{
+ if( node->m_mark ) {
+ if( ( depth == node->m_inmap.m_depth )
+ || ( VF_NODE_CODE_RANGE != node->m_type ) ) {
+ // consistent stack depth in the node
+ return VER_OK;
+ } else {
+ // inconsistent stack depth
+ VF_REPORT( ctx, "Inconsistent stack depth: "
+ << node->m_inmap.m_depth << " != " << depth );
+ return VER_ErrorStackDepth;
+ }
+ }
+ // mark the node
+ node->m_mark = VF_START_MARK;
+
+ // count the node
+ vf_Graph *graph = ctx->m_graph;
+ graph->IncrementReachableCount();
+ node->m_inmap.m_depth = depth;
+
+ if( VF_NODE_CODE_RANGE != node->m_type ) {
+ if( VF_NODE_HANDLER == node->m_type ) {
+ depth = 1;
+ node->m_stack = 1;
+ node->m_outmap.m_depth = 1;
+ } else if( VF_NODE_END_ENTRY == node->m_type ) {
+ return VER_OK;
+ }
+ return VER_Continue;
+ }
+ // calculate a stack depth after the last node instruction
+ int stack_depth = 0;
+ for( vf_InstrHandle instr = node->m_start; instr <= node->m_end; instr++ ) {
+ if( instr->m_minstack > depth ) {
+ VF_REPORT( ctx, "Unable to pop operand off an empty stack" );
+ return VER_ErrorStackOverflow;
+ }
+ stack_depth += instr->m_stack;
+ depth += instr->m_stack;
+ if( depth > ctx->m_maxstack || ( int )depth < 0 ) {
+ VF_REPORT( ctx, "Instruction stack overflow" );
+ return VER_ErrorStackOverflow;
+ }
+ }
- /**
- * Evaluate stack depth
- */
- int result = 0;
- for( vf_Code_t * pointer = start; pointer <= end; pointer++ ) {
- result += pointer->m_stack;
+ node->m_stack = stack_depth;
+ node->m_outmap.m_depth = depth;
+ return VER_Continue;
+} // vf_check_node_stack_depth
+
+/**
+ * Checks graph nodes stack depth consistency recursively.
+ * Returns result of a check.
+ */
+static vf_Result
+vf_check_stack_depth( vf_Node *node, // a graph node
+ unsigned stack_depth, // initial stack depth of node
+ vf_Context *ctx ) // verification context
+{
+ // check for node stack overflow
+ vf_Result result = vf_check_node_stack_depth( node, stack_depth, ctx );
+ if( result != VER_Continue ) {
+ return result;
}
- return result;
-} // vf_get_node_stack_depth
+ // iterate over out edges and set stack depth for out nodes
+ for( vf_EdgeHandle outedge = node->m_outedge;
+ outedge; outedge = outedge->m_outnext ) {
+ // get out node
+ vf_Node *outnode = (vf_Node*)outedge->m_end;
+ // mark out node with its out nodes
+ result = vf_check_stack_depth( outnode, stack_depth, ctx );
+ if( VER_OK != result ) {
+ return result;
+ }
+ }
+ return VER_OK;
+} // vf_check_stack_depth
+/**
+ * Removes in edge from the list of the corresponding end node.
+ */
+static void
+vf_remove_inedge( vf_EdgeHandle edge ) // verification context
+{
+ vf_EdgeHandle *p_next_edge = (vf_EdgeHandle*) & edge->m_end->m_inedge;
+ vf_Edge *inedge = (vf_Edge*) edge->m_end->m_inedge;
+ while( inedge ) {
+ if( inedge == edge ) {
+ // remove the edge from the list
+ *p_next_edge = inedge->m_innext;
+ return;
+ }
+ p_next_edge = &inedge->m_innext;
+ inedge = (vf_Edge*) inedge->m_innext;
+ }
+ VF_DIE( "vf_remove_inedge: Cannot find an IN edge " << edge
+ << " from the list of the node " << edge->m_end );
+}
+
+/**
+ * Scans dead nodes, removes obsolete edges and fills corresponding bytecode by nop
+ * instruction.
+ */
+static void
+vf_nullify_unreachable_bytecode( vf_ContextHandle ctx ) // verification context
+{
+ vf_Node *node =
+ (vf_Node*)ctx->m_graph->GetStartNode()->m_outedge->m_end;
+ for( ; node->m_type != VF_NODE_END_ENTRY; node++ ) {
+ assert( VF_NODE_CODE_RANGE == node->m_type );
+ if( !node->m_mark ) {
+ unsigned char *instr = node->m_start->m_addr;
+ const unsigned char *end = vf_get_instr_end( node->m_end, ctx );
+ while( instr < end ) {
+ *( instr++ ) = OPCODE_NOP;
+ }
+ node->m_stack = 0;
+ // we assume that java compiler generally doesn't generate a dead code,
+ // so we rarely remove edges here is rare
+ for( vf_EdgeHandle edge = node->m_outedge; edge;
+ edge = edge->m_outnext ) {
+ vf_remove_inedge( edge );
+ }
+ node->m_inedge = node->m_outedge = NULL;
+ node->m_outnum = 0;
+ }
+ }
+}
/**
- * Function provides some checks of control flow and data flow structures of graph.
+ * Provides checks of control flow and data flow structures of graph.
*/
-Verifier_Result
-vf_check_graph( vf_Context_t * ctex ) // verifier context
+vf_Result
+vf_check_graph( vf_Context *ctx ) // verification context
{
- unsigned count, inedge, innode;
+ vf_Graph *graph = ctx->m_graph;
+ vf_InstrHandle instr = ctx->m_instr;
- /**
- * Gem method max stack
- */
- vf_Graph *vGraph = ctex->m_graph;
- unsigned maxstack = method_get_max_stack( ctex->m_method );
- unsigned short handlcount =
- method_get_exc_handler_number( ctex->m_method );
- vf_Code_t *code = ctex->m_code;
+ vf_Result result;
- /**
- * Check stack depth correspondence
- */
- unsigned index = 1;
- Verifier_Result result = vf_check_stack_depth( 0, VERIFY_START_MARK,
- maxstack +
- VERIFY_START_MARK, &index,
- ctex );
- if( result != VER_OK ) {
- goto labelEnd_bypassGraphStructure;
- }
- assert( index <= vGraph->GetNodeCount() );
+ // allocate a current stack map vector
+ ctx->m_map = (vf_MapVector*)vf_palloc( ctx->m_pool,
+ sizeof( vf_MapVector ) );
+ ctx->m_graph->AllocVector( ctx->m_map );
- /**
- * Determine dead code nodes
- */
- index = vGraph->GetNodeCount() - index; // number of dead code nodes
+ // create a buf stack map vector (max 4 entries)
+ ctx->m_buf = (vf_MapEntry*)vf_palloc( ctx->m_pool,
+ sizeof( vf_MapEntry )
+ * ctx->m_maxstack );
- /**
- * Override all dead nodes
- */
- if( index ) {
- /**
- * Identify dead code nodes and fill by nop instruction.
- */
- for( index = handlcount + 1; index < vGraph->GetNodeCount() - 1;
- index++ ) {
- if( !vGraph->IsNodeMarked( index ) ) {
- unsigned char *instr =
- code[vGraph->GetNodeFirstInstr( index )].m_addr;
- unsigned len =
- vGraph->GetNodeBytecodeLen( ctex,
- vGraph->GetNode( index ) );
- for( count = 0; count < len; count++ ) {
- instr[count] = OPCODE_NOP;
- }
- vGraph->SetNodeStackModifier( index, 0 );
- }
- }
+ if( ctx->m_retnum ) {
+ result = vf_mark_subroutines( ctx );
+ } else {
+ result =
+ vf_check_stack_depth( (vf_Node*)graph->GetStartNode(), 0,
+ ctx );
+ }
+ if( VER_OK != result ) {
+ return result;
}
-#if _VERIFY_DEBUG
- if( ctex->m_dump.m_mod_graph ) {
- vGraph->DumpGraph( ctex );
+ // there could be only nop opcodes in the bytecode, in this case
+ // the code is already checked during previous step
+ if( ctx->m_maxstack == 0 ) {
+ return VER_OK;
}
- if( ctex->m_dump.m_dot_mod_graph ) {
- vGraph->DumpDotGraph( ctex );
+ // override all dead nodes
+ assert( graph->GetReachableNodeCount() <= graph->GetNodeCount() );
+ if( graph->GetReachableNodeCount() < graph->GetNodeCount() ) {
+ vf_nullify_unreachable_bytecode( ctx );
+ }
+
+ if( ctx->m_retnum ) {
+ result = vf_inline_subroutines( ctx );
+ if( VER_OK != result ) {
+ return result;
+ }
}
-#endif // _VERIFY_DEBUG
+
+ VF_DUMP( DUMP_MOD, graph->DumpGraph() );
+ VF_DUMP( DUMP_DOT_MOD, graph->DumpDotGraph() );
/**
* Check that execution flow terminates with
* return or athrow bytecodes.
* Override all incoming edges to the end-entry node.
*/
- for( inedge = vGraph->GetNodeFirstInEdge( vGraph->GetNodeCount() - 1 );
- inedge; inedge = vGraph->GetEdgeNextInEdge( inedge ) ) {
+ for( vf_EdgeHandle inedge =
+ graph->GetEndNode()->m_inedge; inedge;
+ inedge = inedge->m_innext ) {
// get incoming node
- innode = vGraph->GetEdgeStartNode( inedge );
- // check last node instruction, skip dead code nodes
- if( vGraph->IsNodeMarked( innode ) ) {
- // get node last instruction
- unsigned char *instr =
- code[vGraph->GetNodeLastInstr( innode )].m_addr;
- if( !instr || !( ( *instr ) >= OPCODE_IRETURN && ( *instr ) <= OPCODE_RETURN || ( *instr ) == OPCODE_ATHROW ) ) { // illegal instruction
- VERIFY_REPORT_METHOD( ctex,
- "Falling off the end of the code" );
- result = VER_ErrorCodeEnd;
- goto labelEnd_bypassGraphStructure;
- }
+ vf_NodeHandle innode = inedge->m_start;
+ // get node last instruction
+ vf_InstrType type = innode->m_end->m_type;
+
+ if( ( VF_INSTR_RETURN != type ) && ( VF_INSTR_THROW != type ) ) {
+ // illegal instruction
+ VF_REPORT( ctx, "Falling off the end of the code" );
+ return VER_ErrorCodeEnd;
}
}
/**
* Make data flow analysis
*/
- result = vf_check_graph_data_flow( ctex );
+ result = vf_check_graph_data_flow( ctx );
- labelEnd_bypassGraphStructure:
return result;
} // vf_check_graph
@@ -851,144 +743,13 @@ vf_check_graph( vf_Context_t * ctex )
* Frees memory allocated for graph, if any.
*/
void
-vf_free_graph( vf_Context_t * context ) // verifier context
+vf_free_graph( vf_Context *ctx ) // verification context
{
- if( context->m_graph ) {
- context->m_graph->~vf_Graph();
- context->m_graph = NULL;
+ if( ctx->m_graph ) {
+ VF_TRACE( "method", VF_REPORT_CTX( ctx ) << "method graph: "
+ << " nodes: " << ctx->m_graph->GetNodeCount()
+ << ", edges: " << ctx->m_graph->GetEdgeCount() );
+ ctx->m_graph->~vf_Graph();
+ ctx->m_graph = NULL;
}
} // vf_free_graph
-
-/**
- * Function checks stack overflow of graph node instruction.
- */
-static inline Verifier_Result
-vf_check_node_stack_depth( unsigned nodenum, // graph node number
- int depth, // initial stack depth
- unsigned max_stack, // maximal stack
- vf_Context_t * ctex ) // verifier context
-{
- // get checked node
- vf_NodeHandle node = ctex->m_graph->GetNode( nodenum );
-
- /**
- * For start, end and handler nodes
- */
- if( node->m_type != VF_TYPE_NODE_CODE_RANGE ) {
- return VER_OK;
- }
-
- /**
- * Get begin and end code instruction of graph node
- */
- unsigned start = node->m_start;
- unsigned end = node->m_end;
- assert( start <= end );
-
- /**
- * Evaluate stack depth
- */
- unsigned index;
- vf_Code_t *pointer;
- int stack_depth = 0;
- for( index = start, pointer = &ctex->m_code[index]; index <= end;
- index++, pointer++ ) {
- if( pointer->m_minstack + VERIFY_START_MARK > stack_depth + depth ) {
- VERIFY_REPORT_METHOD( ctex,
- "Unable to pop operand off an empty stack" );
- return VER_ErrorStackOverflow;
- }
- stack_depth += pointer->m_stack;
- if( stack_depth + depth > ( int )max_stack
- || stack_depth + depth < VERIFY_START_MARK ) {
- VERIFY_REPORT_METHOD( ctex, "Instruction stack overflow" );
- return VER_ErrorStackOverflow;
- }
- }
-#if _VERIFY_DEBUG
- if( stack_depth != ctex->m_graph->GetNodeStackModifier( nodenum ) ) {
- VERIFY_DEBUG
- ( "vf_check_node_stack_depth: error stack modifier calculate" );
- vf_error();
- }
-#endif // _VERIFY_DEBUG
-
- return VER_OK;
-} // vf_check_node_stack_depth
-
-/**
- * Function checks graph nodes stack depth consistency. It's recursive function.
- * Function returns result of check.
- */
-static Verifier_Result
-vf_check_stack_depth( unsigned nodenum, // graph node number
- int stack_depth, // initial stack depth of node
- unsigned maxstack, // maximal stack
- unsigned *count, // pointer to checked node count
- vf_Context_t * ctex ) // verifier context
-{
- // get checked node
- vf_NodeHandle node = ctex->m_graph->GetNode( nodenum );
-
- /**
- * Skip end-entry node
- */
- if( VF_TYPE_NODE_END_ENTRY == node->m_type ) {
- return VER_OK;
- }
-
- /**
- * Check handler node
- */
- if( VF_TYPE_NODE_HANDLER == node->m_type ) {
- // Reset stack for handler nodes
- stack_depth = VERIFY_START_MARK;
- }
-
- /**
- * Check node stack depth
- */
- int depth = ctex->m_graph->GetNodeMark( nodenum );
- if( !depth ) {
- // stack depth don't set, mark node by his stack depth
- ctex->m_graph->SetNodeMark( nodenum, stack_depth );
- ( *count )++;
- } else {
- if( stack_depth == depth ) {
- // consistent stack depth in graph
- return VER_OK;
- } else {
- // inconsistent stack depth in graph
- VERIFY_REPORT_METHOD( ctex, "Inconsistent stack depth: "
- << stack_depth - VERIFY_START_MARK << " != "
- << depth - VERIFY_START_MARK );
- return VER_ErrorStackDeep;
- }
- }
-
- /**
- * Check node stack overflow
- */
- Verifier_Result result =
- vf_check_node_stack_depth( nodenum, stack_depth, maxstack, ctex );
- if( result != VER_OK ) {
- return result;
- }
-
- /**
- * Override all out edges and set stack depth for out nodes
- */
- depth = stack_depth + ctex->m_graph->GetNodeStackModifier( nodenum );
- for( unsigned outedge = ctex->m_graph->GetNodeFirstOutEdge( nodenum );
- outedge; outedge = ctex->m_graph->GetEdgeNextOutEdge( outedge ) ) {
- // get out node
- unsigned outnode = ctex->m_graph->GetEdgeEndNode( outedge );
- // mark out node with its out nodes
- result =
- vf_check_stack_depth( outnode, depth, maxstack, count, ctex );
- if( result != VER_OK ) {
- return result;
- }
- }
- return result;
-} // vf_check_stack_depth
diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\ver_dataflow.cpp 91/trunk/working_vm/vm/vmcore/src/verifier\ver_dataflow.cpp
--- 9/trunk/working_vm/vm/vmcore/src/verifier\ver_dataflow.cpp Tue Mar 20 19:34:53 2007
+++ 91/trunk/working_vm/vm/vmcore/src/verifier\ver_dataflow.cpp Tue Apr 03 19:59:03 2007
@@ -34,13 +34,13 @@
**************** Graph Data Flow Analysis ******************
************************************************************/
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
/**
- * Function prints stack map entry into output stream.
+ * Prints stack map entry into output stream.
*/
static void
-vf_dump_vector_entry( vf_MapEntry_t * entry, // stack map entry
+vf_dump_vector_entry( vf_MapEntry *entry, // stack map entry
ostream *stream ) // output stream
{
switch ( entry->m_type ) {
@@ -81,18 +81,20 @@ vf_dump_vector_entry( vf_MapEntry_t * en
case SM_UNINITIALIZED_THIS:
*stream << " [THIS]";
break;
+ case SM_ANY:
+ *stream << " [ANY ]";
+ break;
default:
*stream << " [? " << entry->m_type << "]";
}
- return;
} // vf_dump_vector_entry
/**
- * Function prints data flow vector into output stream.
+ * Prints data flow vector into output stream.
*/
void
vf_dump_vector( vf_MapVectorHandle vector, // data flow vector
- vf_Code_t * code, // code instruction
+ vf_InstrHandle instr, // code instruction
ostream *stream ) // output stream (can be NULL)
{
unsigned index, count;
@@ -102,10 +104,10 @@ vf_dump_vector( vf_MapVectorHandle vecto
stream = &cerr;
}
// dump code instruction if it's needed
- if( code != NULL ) {
- *stream << ( ( code->m_stack < 0 ) ? "[" : "[ " )
- << code->m_stack << "| " << code->m_minstack << "] "
- << vf_opcode_names[*( code->m_addr )] << endl;
+ if( instr != NULL ) {
+ *stream << ( ( instr->m_stack < 0 ) ? "[" : "[ " )
+ << instr->m_stack << "| " << instr->m_minstack << "] "
+ << vf_opcode_names[*( instr->m_addr )] << endl;
}
// dump locals vector
*stream << "L:";
@@ -133,7 +135,7 @@ vf_dump_vector( vf_MapVectorHandle vecto
continue;
}
if( vector->m_local[index].m_vtype ) {
- vf_ValidType_t *type = vector->m_local[index].m_vtype;
+ vf_ValidType *type = vector->m_local[index].m_vtype;
*stream << type;
for( count = 0; count < type->number; count++ ) {
*stream << " " << type->string[count];
@@ -169,7 +171,7 @@ vf_dump_vector( vf_MapVectorHandle vecto
continue;
}
if( vector->m_stack[index].m_vtype ) {
- vf_ValidType_t *type = vector->m_stack[index].m_vtype;
+ vf_ValidType *type = vector->m_stack[index].m_vtype;
*stream << type;
for( count = 0; count < type->number; count++ ) {
*stream << " " << type->string[count];
@@ -179,17 +181,16 @@ vf_dump_vector( vf_MapVectorHandle vecto
}
*stream << endl;
}
- return;
} // vf_dump_vector
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
/**
* Function compares two valid types.
*/
bool
-vf_is_types_equal( vf_ValidType_t * type1, // first checked type
- vf_ValidType_t * type2 ) // second checked type
+vf_is_types_equal( vf_ValidType *type1, // first checked type
+ vf_ValidType *type2 ) // second checked type
{
if( type1 == type2 ) {
return true;
@@ -214,14 +215,10 @@ static inline bool
vf_merge_vectors( vf_MapVector *first, // first vector
vf_MapVectorHandle second, // second vector
bool handler_flag, // if merged node is handler
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
bool is_changed = false;
- vf_MapEntry_t zero = { 0 };
-
- // check vectors parameters
- assert( first->m_maxlocal == second->m_maxlocal );
- assert( first->m_maxstack == second->m_maxstack );
+ vf_MapEntry zero = { 0 };
// merge local variable vector
unsigned index;
@@ -240,9 +237,9 @@ vf_merge_vectors( vf_MapVector *first,
is_changed = true;
} else if( first->m_local[index].m_type == SM_REF ) {
// reference types, merge them
- vf_ValidType_t *type =
- ctex->m_type->MergeTypes( first->m_local[index].m_vtype,
- second->m_local[index].m_vtype );
+ vf_ValidType *type =
+ ctx->m_type->MergeTypes( first->m_local[index].m_vtype,
+ second->m_local[index].m_vtype );
if( type ) {
// set merged type
first->m_local[index].m_vtype = type;
@@ -250,9 +247,9 @@ vf_merge_vectors( vf_MapVector *first,
}
} else if( first->m_local[index].m_type == SM_UNINITIALIZED ) {
// reference types, merge them
- vf_ValidType_t *type =
- ctex->m_type->MergeTypes( first->m_local[index].m_vtype,
- second->m_local[index].m_vtype );
+ vf_ValidType *type =
+ ctx->m_type->MergeTypes( first->m_local[index].m_vtype,
+ second->m_local[index].m_vtype );
if( type
|| first->m_local[index].m_new !=
second->m_local[index].m_new ) {
@@ -297,9 +294,9 @@ vf_merge_vectors( vf_MapVector *first,
is_changed = true;
} else if( first->m_stack[index].m_type == SM_REF ) {
// reference types, merge them
- vf_ValidType_t *type =
- ctex->m_type->MergeTypes( first->m_stack[index].m_vtype,
- second->m_stack[index].m_vtype );
+ vf_ValidType *type =
+ ctx->m_type->MergeTypes( first->m_stack[index].m_vtype,
+ second->m_stack[index].m_vtype );
if( type ) {
// set merged type
first->m_stack[index].m_vtype = type;
@@ -307,9 +304,9 @@ vf_merge_vectors( vf_MapVector *first,
}
} else if( first->m_stack[index].m_type == SM_UNINITIALIZED ) {
// reference types, merge them
- vf_ValidType_t *type =
- ctex->m_type->MergeTypes( first->m_stack[index].m_vtype,
- second->m_stack[index].m_vtype );
+ vf_ValidType *type =
+ ctx->m_type->MergeTypes( first->m_stack[index].m_vtype,
+ second->m_stack[index].m_vtype );
if( type
|| first->m_stack[index].m_new !=
second->m_stack[index].m_new ) {
@@ -323,37 +320,6 @@ vf_merge_vectors( vf_MapVector *first,
} // vf_merge_vectors
/**
- * Function copies source vector to data vector.
- */
-static inline void
-vf_copy_vector( vf_MapVectorHandle source, // copied vector
- vf_MapVector *data ) // data vector
-{
- unsigned index;
- vf_MapEntry_t zero = { 0 };
-
- assert( source->m_maxlocal <= data->m_maxlocal );
- assert( source->m_maxstack <= data->m_maxstack );
- // copy locals
- data->m_number = source->m_number;
- for( index = 0; index < source->m_number; index++ ) {
- data->m_local[index] = source->m_local[index];
- }
- for( ; index < data->m_maxlocal; index++ ) {
- data->m_local[index] = zero;
- }
- // copy stack
- data->m_depth = source->m_depth;
- for( index = 0; index < source->m_depth; index++ ) {
- data->m_stack[index] = source->m_stack[index];
- }
- for( ; index < data->m_maxstack; index++ ) {
- data->m_stack[index] = zero;
- }
- return;
-} // vf_copy_vector
-
-/**
* Function compares two vectors.
*/
static inline bool
@@ -361,9 +327,7 @@ vf_compare_vectors( vf_MapVectorHandle f
vf_MapVectorHandle second ) // second vector
{
// compare vector parameters
- if( first->m_maxlocal != second->m_maxlocal
- || first->m_maxstack != second->m_maxstack
- || first->m_number != second->m_number
+ if( first->m_number != second->m_number
|| first->m_depth != second->m_depth ) {
return false;
}
@@ -393,41 +357,41 @@ vf_compare_vectors( vf_MapVectorHandle f
/**
* Function check access constraint for two stack map references.
*/
-static inline Verifier_Result
-vf_check_access( vf_MapEntry_t * source, // stack map entry
- vf_MapEntry_t * target, // required map entry
- vf_Context_t * ctex ) // verifier context
+static inline vf_Result
+vf_check_access( vf_MapEntry *source, // stack map entry
+ vf_MapEntry *target, // required map entry
+ vf_Context *ctx ) // verification context
{
// compare types
assert( target->m_vtype->number == 1 );
- vf_CheckConstraint_t check = ( target->m_ctype == VF_CHECK_ACCESS_FIELD )
+ vf_CheckConstraint check = ( target->m_ctype == VF_CHECK_ACCESS_FIELD )
? VF_CHECK_ASSIGN : VF_CHECK_PARAM;
for( unsigned index = 0; index < source->m_vtype->number; index++ ) {
// set constraints for differing types
if( target->m_vtype->string[0] != source->m_vtype->string[index] ) {
- ctex->m_type->SetRestriction( target->m_vtype->string[0],
- source->m_vtype->string[index], 0,
- check );
+ ctx->m_type->SetRestriction( target->m_vtype->string[0],
+ source->m_vtype->string[index], 0,
+ check );
}
// set access constraints for differing types
- if( ctex->m_vtype.m_class->string[0] !=
+ if( ctx->m_vtype.m_class->string[0] !=
source->m_vtype->string[index] ) {
// not the same class
- Verifier_Result result =
+ vf_Result result =
vf_check_access_constraint( target->m_vtype->string[0],
source->m_vtype->string[index],
target->m_index,
- ( vf_CheckConstraint_t ) target->
- m_ctype, ctex );
+ ( vf_CheckConstraint )
+ target->m_ctype,
+ ctx );
if( result == VER_ClassNotLoaded ) {
// cannot complete check, set restriction
- ctex->m_type->SetRestriction( ctex->m_vtype.m_class->
- string[0],
- source->m_vtype->string[index],
- 0,
- ( vf_CheckConstraint_t )
- target->m_ctype );
- } else if( result != VER_OK ) {
+ ctx->m_type->SetRestriction( ctx->m_vtype.m_class->
+ string[0],
+ source->m_vtype->string[index],
+ 0, ( vf_CheckConstraint )
+ target->m_ctype );
+ } else if( VER_OK != result ) {
// return error
return result;
}
@@ -437,28 +401,42 @@ vf_check_access( vf_MapEntry_t * source,
} // vf_check_access
/**
- * Function checks two stack map references.
+ * Checks two stack map references.
*/
-static inline Verifier_Result
-vf_check_entry_refs( vf_MapEntry_t * source, // stack map entry
- vf_MapEntry_t * target, // required map entry
+static inline vf_Result
+vf_check_entry_refs( vf_MapEntry *source, // stack map entry
+ vf_MapEntry *target, // required map entry
bool local_init, // initialization flag of locals
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- // check entries type
- if( !( source->m_type == SM_REF || source->m_type == SM_UNINITIALIZED )
- || !( target->m_type == SM_REF
- || target->m_type == SM_UNINITIALIZED ) ) {
- return VER_ErrorDataFlow;
- }
// check local variable type
if( source->m_is_local
&& ( !target->m_is_local || source->m_local != target->m_local ) ) {
return VER_ErrorDataFlow;
}
+ // check entries type
+ if( !( SM_REF == source->m_type || SM_UNINITIALIZED == source->m_type )
+ || !( SM_REF == target->m_type
+ || SM_UNINITIALIZED == target->m_type ) ) {
+ if( SM_ANY == source->m_type ) {
+ return VER_OK;
+ }
+ // only aload and astore get SM_REF/VF_CHECK_UNINITIALIZED_THIS
+ if( SM_RETURN_ADDR == source->m_type
+ && VF_CHECK_UNINITIALIZED_THIS == target->m_ctype ) {
+ if( source->m_is_local ) {
+ // aload a return address
+ return VER_ErrorJsrLoadRetAddr;
+ } else if( !target->m_is_local ) {
+ // astore a return address
+ return VER_OK;
+ }
+ }
+ return VER_ErrorDataFlow;
+ }
// check available entry
if( source->m_vtype == NULL ) {
- // nothing checks
+ // nothing to check
return VER_OK;
}
// check initialization
@@ -467,7 +445,7 @@ vf_check_entry_refs( vf_MapEntry_t * sou
if( ( source->m_new == 0 && target->m_ctype == VF_CHECK_ACCESS_FIELD )
|| ( local_init == false
&& target->m_ctype == VF_CHECK_UNINITIALIZED_THIS )
- || ( !ctex->m_dump.m_verify && source->m_new == 0
+ || ( !ctx->m_verify_all && source->m_new == 0
&& target->m_ctype == VF_CHECK_UNINITIALIZED_THIS ) ) {
// 1. In initialization method instance fields of this
// that are declared in the current class may be assigned
@@ -480,7 +458,7 @@ vf_check_entry_refs( vf_MapEntry_t * sou
// can be stored in a local variable if backward branch is
// taken or the code is protected by exception handler.
} else {
- VERIFY_REPORT_METHOD( ctex, "Uninitialized reference usage" );
+ VF_REPORT( ctx, "Uninitialized reference usage" );
return VER_ErrorDataFlow;
}
}
@@ -491,53 +469,55 @@ vf_check_entry_refs( vf_MapEntry_t * sou
case VF_CHECK_UNINITIALIZED_THIS:
case VF_CHECK_PARAM: // check method invocation conversion
if( target->m_vtype != NULL ) {
- is_error = ctex->m_type->CheckTypes( target->m_vtype,
- source->m_vtype, 0,
- VF_CHECK_PARAM );
+ is_error = ctx->m_type->CheckTypes( target->m_vtype,
+ source->m_vtype, 0,
+ VF_CHECK_PARAM );
}
break;
case VF_CHECK_ARRAY: // check if source reference is array
is_error =
- ctex->m_type->CheckTypes( NULL, source->m_vtype, 0,
- VF_CHECK_ARRAY );
+ ctx->m_type->CheckTypes( NULL, source->m_vtype, 0,
+ VF_CHECK_ARRAY );
break;
case VF_CHECK_REF_ARRAY:
is_error =
- ctex->m_type->CheckTypes( NULL, source->m_vtype, 0,
- VF_CHECK_REF_ARRAY );
+ ctx->m_type->CheckTypes( NULL, source->m_vtype, 0,
+ VF_CHECK_REF_ARRAY );
break;
case VF_CHECK_EQUAL: // check if references are equal
- is_error = ctex->m_type->CheckTypes( target->m_vtype,
- source->m_vtype, 0,
- VF_CHECK_EQUAL );
+ is_error = ctx->m_type->CheckTypes( target->m_vtype,
+ source->m_vtype, 0,
+ VF_CHECK_EQUAL );
break;
case VF_CHECK_ASSIGN: // check assignment conversion
case VF_CHECK_ASSIGN_WEAK: // check weak assignment conversion
assert( target->m_vtype != NULL );
- is_error = ctex->m_type->CheckTypes( target->m_vtype,
- source->m_vtype, 0,
- ( vf_CheckConstraint_t ) target->
- m_ctype );
+ is_error = ctx->m_type->CheckTypes( target->m_vtype,
+ source->m_vtype, 0,
+ ( vf_CheckConstraint ) target->
+ m_ctype );
break;
case VF_CHECK_ACCESS_FIELD: // check field access
case VF_CHECK_ACCESS_METHOD: // check method access
{
assert( target->m_vtype != NULL ); // not null reference
assert( target->m_local != 0 ); // constant pool index is set
- Verifier_Result result = vf_check_access( source, target, ctex );
+ vf_Result result = vf_check_access( source, target, ctx );
return result;
}
break;
case VF_CHECK_DIRECT_SUPER: // check is target class is direct super class of source
- is_error = ctex->m_type->CheckTypes( target->m_vtype, source->m_vtype,
- 0, VF_CHECK_DIRECT_SUPER );
+ is_error =
+ ctx->m_type->CheckTypes( target->m_vtype, source->m_vtype, 0,
+ VF_CHECK_DIRECT_SUPER );
break;
case VF_CHECK_INVOKESPECIAL: // check invokespecial object reference
- is_error = ctex->m_type->CheckTypes( target->m_vtype, source->m_vtype,
- 0, VF_CHECK_INVOKESPECIAL );
+ is_error =
+ ctx->m_type->CheckTypes( target->m_vtype, source->m_vtype, 0,
+ VF_CHECK_INVOKESPECIAL );
break;
default:
- LDIE( 38, "Verifier: vf_check_entry_refs: unknown check in switch" );
+ VF_DIE( "vf_check_entry_refs: unknown check in switch" );
}
// check error
if( is_error ) {
@@ -548,24 +528,32 @@ vf_check_entry_refs( vf_MapEntry_t * sou
} // vf_check_entry_refs
/**
- * Function checks two stack map entries.
+ * Checks two stack map entries.
*/
-static inline Verifier_Result
-vf_check_entry_types( vf_MapEntry_t * entry1, // stack map entry
- vf_MapEntry_t * entry2, // required map entry
+static inline vf_Result
+vf_check_entry_types( vf_MapEntry *entry1, // stack map entry
+ vf_MapEntry *entry2, // required map entry
bool local_init, // initialization flag of locals
bool *need_copy, // pointer to copy flag
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
+ if( SM_ANY == entry1->m_type ) {
+ return VER_OK;
+ }
switch ( entry2->m_type ) {
case SM_REF:
// check reference entries
{
- Verifier_Result result =
- vf_check_entry_refs( entry1, entry2, local_init, ctex );
+ vf_Result result =
+ vf_check_entry_refs( entry1, entry2, local_init, ctx );
*need_copy = true;
return result;
}
+ case SM_RETURN_ADDR:
+ if( entry1->m_type != entry2->m_type ) {
+ return VER_ErrorDataFlow;
+ }
+ *need_copy = true;
break;
case SM_TOP:
case SM_INT:
@@ -617,34 +605,33 @@ vf_check_entry_types( vf_MapEntry_t * en
* Function creates array element valid type.
*/
static inline void
-vf_set_array_element_type( vf_MapEntry_t * buf, // result data flow vector entry
- vf_MapEntry_t * vector, // data flow vector entry
- vf_MapEntry_t * array, // array data flow vector entry
- vf_Context_t * ctex ) // verifier context
+vf_set_array_element_type( vf_MapEntry *buf, // result data flow vector entry
+ vf_MapEntry *vector, // data flow vector entry
+ vf_MapEntry *array, // array data flow vector entry
+ vf_ContextHandle ctx ) // verification context
{
- assert( array->m_type == SM_REF );
+ assert( SM_REF == array->m_type || SM_ANY == array->m_type );
buf->m_type = array->m_type;
buf->m_vtype = array->m_vtype;
buf->m_local = vector->m_local;
buf->m_is_local = vector->m_is_local;
if( buf->m_vtype ) {
// create cell array type
- buf->m_vtype = ctex->m_type->NewArrayElemType( buf->m_vtype );
+ buf->m_vtype = ctx->m_type->NewArrayElemType( buf->m_vtype );
}
- return;
} // vf_set_array_element_type
/**
- * Function receives IN data flow vector entry for code instruction.
+ * Receives IN data flow vector entry for code instruction.
*/
-static inline vf_MapEntry_t *
-vf_set_new_in_vector( vf_Code_t * code, // code instruction
- vf_MapEntry_t * vector, // data flow vector entry
- vf_MapEntry_t * stack_buf, // stack map vector
- vf_Context_t * ctex ) // verifier context
+static inline vf_MapEntry *
+vf_set_new_in_vector( vf_InstrHandle instr, // code instruction
+ vf_MapEntry *vector, // data flow vector entry
+ vf_ContextHandle ctx ) // verification context
{
short number;
- vf_MapEntry_t *newvector;
+ vf_MapEntry *stack_buf = ctx->m_buf;
+ vf_MapEntry *newvector;
switch ( vector->m_type ) {
case SM_COPY_0:
@@ -653,12 +640,12 @@ vf_set_new_in_vector( vf_Code_t * code,
case SM_COPY_3:
// it's a copy type, copy value from IN vector
number = ( short )( vector->m_type - SM_COPY_0 );
- assert( number < code->m_inlen );
- newvector = &code->m_invector[number];
+ assert( number < instr->m_inlen );
+ newvector = &instr->m_invector[number];
if( newvector->m_type == SM_TOP
|| newvector->m_type >= SM_WORD
- || ( newvector->m_type == SM_REF && newvector->m_vtype == NULL ) )
- {
+ || ( newvector->m_type == SM_REF
+ && newvector->m_vtype == NULL ) ) {
// copy value from saved stack entry
newvector = &stack_buf[number];
newvector->m_local = vector->m_local;
@@ -668,7 +655,7 @@ vf_set_new_in_vector( vf_Code_t * code,
case SM_UP_ARRAY:
// set reference array element
newvector = &stack_buf[0];
- vf_set_array_element_type( newvector, vector, &stack_buf[0], ctex );
+ vf_set_array_element_type( newvector, vector, &stack_buf[0], ctx );
break;
default:
newvector = vector;
@@ -678,25 +665,23 @@ vf_set_new_in_vector( vf_Code_t * code,
} // vf_set_new_in_vector
/**
- * Function sets OUT data flow vector for code instruction.
+ * Sets OUT data flow vector for code instruction.
*/
static inline void
-vf_set_instruction_out_vector( vf_Code_t * code, // code instruction
- vf_MapEntry_t * stack, // stack map vector
- vf_MapEntry_t * locals, // local variable vector
+vf_set_instruction_out_vector( vf_InstrHandle instr, // code instruction
+ vf_MapEntry *stack, // stack map vector
+ vf_MapEntry *locals, // local variable vector
unsigned short *number, // pointer to local variables number
- vf_MapEntry_t * buf, // memory buf array
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
unsigned index;
- vf_MapEntry_t *entry, *vector;
+ vf_MapEntry *entry, *vector;
// set instruction out vector
- for( index = 0, vector = code->m_outvector;
- index < code->m_outlen;
- index++, vector = &code->m_outvector[index] ) {
- vf_MapEntry_t *newvector =
- vf_set_new_in_vector( code, vector, buf, ctex );
+ for( index = 0, vector = instr->m_outvector;
+ index < instr->m_outlen;
+ index++, vector = &instr->m_outvector[index] ) {
+ vf_MapEntry *newvector = vf_set_new_in_vector( instr, vector, ctx );
if( newvector->m_is_local ) {
// get local variable
entry = locals + newvector->m_local;
@@ -716,7 +701,6 @@ vf_set_instruction_out_vector( vf_Code_t
entry->m_new = newvector->m_new;
entry->m_vtype = newvector->m_vtype;
}
- return;
} // vf_set_instruction_out_vector
/**
@@ -725,7 +709,7 @@ vf_set_instruction_out_vector( vf_Code_t
static inline void
vf_clear_stack( vf_MapVector *vector ) // map vector
{
- vf_MapEntry_t zero_entry = { 0 };
+ vf_MapEntry zero_entry = { 0 };
// zero stack vector
for( unsigned index = 0; index < vector->m_depth; index++ ) {
@@ -733,51 +717,73 @@ vf_clear_stack( vf_MapVector *vector )
}
vector->m_depth = 0;
- return;
} // vf_clear_stack
/**
- * Function sets stack map vector for return instructions.
+ * Checks that this instance was initialized.
*/
-static inline void
-vf_set_return_out_vector( vf_MapEntry_t * stack, // stack map vector
- vf_MapEntry_t * buf, // stored values vector
- vf_MapEntry_t * invector, // IN data flow vector
- unsigned len, // IN vector length
- vf_Context_t * UNREF ctex ) // verifier context
+static inline vf_Result
+vf_check_initialized_this( vf_MapEntry *locals, // stack map vector
+ vf_Context *ctx ) // verification context
{
- unsigned index;
- vf_MapEntry_t *entry;
-
- // set return instruction out vector
- for( index = 0, entry = invector;
- index < len; index++, entry = &invector[index] ) {
- if( entry->m_type == SM_REF ) {
- stack[index].m_type = buf[index].m_type;
- stack[index].m_vtype = buf[index].m_vtype;
+ // check true if the iterator can be advanced further.
*/
- vf_EdgeHandle GetEdge(unsigned edge_num);
+ bool HasMoreElements() const
+ {
+ return m_container;
+ }
+}; // vf_Iterator
+
+/**
+ * Verifier control flow graph structure.
+ */
+class vf_Graph
+{
+ vf_NodeContainer *m_nodes; ///< array of nodes
+ vf_EdgeContainer *m_edges; ///< array of edges
+ vf_Pool *m_pool; ///< graph memory pool
+ vf_NodeHandle *m_enum; ///< graph node enumeration
+ unsigned m_nodenum; ///< number of nodes
+ unsigned m_edgenum; ///< number of edges
+ unsigned m_enumcount; ///< number of enumerated elements
+ vf_NodeHandle m_endnode; ///< control flow end
+ vf_ContextHandle m_ctx; ///< a verification context
+ vf_Iterator iterator; ///< an embedded graph iterator
+ bool m_free; ///< need to free pool
/**
- * Creates a new edge for graph nodes.
- *
- * @param start_node - start edge node
- * @param end_node - end edge node
- * @note Edge is set as out edge for start_node and as in edge for end_node.
+ * Prints a graph node in stderr.
+ * @param node a graph node
*/
- void NewEdge(unsigned start_node, unsigned end_node);
+ void DumpNode(vf_NodeHandle node);
/**
- * Gets the first code instruction of a node.
- * @param node_num the node number
- * @return a number of the first code instruction of graph node
- * @note Assertion is raised if node_num is not a
- * code range node.
+ * Prints graph node instructions in stderr.
+ * @param node_num a graph node
+ * @note Empty in release mode.
*/
- unsigned GetNodeFirstInstr(unsigned node_num)
- {
- vf_NodeHandle node = GetNode(node_num);
- assert(VF_TYPE_NODE_CODE_RANGE == node->m_type);
- return node->m_start;
- } // GetNodeFirstInstr
+ void DumpNodeInternal(vf_NodeHandle node);
+#ifdef _VF_DEBUG
/**
- * Gets the last code instruction of a node.
- * @param node_num the node number
- * @return a number of the last code instruction of graph node
- * @note Assertion is raised if node_num is not a
- * code range node.
+ * Prints subroutine information in stderr.
+ * @param sub a subroutine handle
*/
- unsigned GetNodeLastInstr(unsigned node_num)
- {
- vf_NodeHandle node = GetNode(node_num);
- assert(VF_TYPE_NODE_CODE_RANGE == node->m_type);
- return node->m_end;
- } // GetNodeLastInstr
+ void DumpSub(vf_SubHandle sub);
/**
- * Gets a bytecode length of a graph node instructions.
- * @param context a verifier context handle
- * @param node a node handle
- * @return a number of the last code instruction of graph node
- * @note Assertion is raised if node_num is not a
- * code range node.
+ * Checks if node maps are allocated.
+ * @param[in] vector to check
*/
- unsigned GetNodeBytecodeLen(vf_ContextHandle context, vf_NodeHandle node)
+ bool AreMapsAllocated(vf_MapVectorHandle vector) const
{
- assert(VF_TYPE_NODE_CODE_RANGE == node->m_type);
- unsigned char *code_end = (node->m_end + 1 == context->m_codeNum)
- ? method_get_bytecode(context->m_method)
- + method_get_code_length(context->m_method)
- : context->m_code[node->m_end + 1].m_addr;
-
- unsigned len = (unsigned) (code_end -
- context->m_code[node->m_start].m_addr);
- return len;
- } // GetNodeBytecodeLen
+ return (!m_ctx->m_maxlocal || vector->m_local)
+ && (!m_ctx->m_maxstack || vector->m_stack);
+ }
+#endif // _VF_DEBUG
/**
- * Gets a stack modifier of a graph node.
- * @param node_num a node number
- * @return a stack modifier of graph node
+ * Dumps a graph header in a file in a DOT format.
+ * @param graph_name a graph name
+ * @param fout a file stream
+ * @note Empty in release mode.
*/
- int GetNodeStackModifier(unsigned node_num)
- {
- return GetNode(node_num)->m_stack;
- } // GetNodeStackModifier
+ void DumpDotHeader(const char *graph_name, ofstream &fout);
/**
- * Sets graph node stack modifier.
- * @param node_num a graph node number
- * @param stack a stack modifier (signed value)
+ * Dumps a graph node in a file in DOT format.
+ * @param node a graph node
+ * @param fout a file stream
+ * @note Empty in release mode.
*/
- void SetNodeStackModifier(unsigned node_num, int stack)
- {
- vf_Node *node = (vf_Node *) GetNode(node_num);
- node->m_stack = stack;
- } // SetNodeStackModifier
+ void DumpDotNode(vf_NodeHandle node, ofstream &fout);
/**
- * Counts graph nodes.
- * @return a number of graph nodes
+ * Dumps graph node instructions in a file stream in DOT format.
+ * @param node a graph node
+ * @param next_node a separator between nodes in stream
+ * @param next_instr a separator between instructions in stream
+ * @param fout an output file stream
+ * @note Empty in release mode.
*/
- unsigned GetNodeCount()
- {
- return m_nodenum;
- } // GetNodeCount
+ void DumpDotNodeInternal(vf_NodeHandle node,
+ char *next_node, char *next_instr, ofstream &fout);
/**
- * Counts graph edges excluding
- * the reserved edge.
- * @return a number of graph edges
+ * Dumps graph end in file in DOT format.
+ * @param fout - output file stream
+ * @note Empty in release mode.
*/
- unsigned GetEdgeCount()
- {
- return m_edgenum - 1;
- } // GetEdgeCount
+ void DumpDotEnd(ofstream &fout);
+public:
/**
- * Marks a graph node with a given number.
- * @param node_num a graph node number
- * @param mark a mark
- */
- void SetNodeMark(unsigned node_num, int mark)
+ * Constructs a control flow graph and allocates memory for
+ * graph structure, nodes and edges.
+ * @param nodenum a number of graph nodes
+ * @param edgenum a number of graph edges
+ * @param ctx a verification context
+ */
+ vf_Graph(unsigned nodenum, unsigned edgenum,
+ vf_ContextHandle ctx):m_nodes(NULL), m_edges(NULL),
+ m_pool(ctx->m_pool), m_enum(NULL), m_nodenum(0), m_edgenum(0),
+ m_enumcount(0), m_ctx(ctx), m_free(false)
{
- vf_Node *node = (vf_Node *) GetNode(node_num);
- node->m_mark = mark;
- } // SetNodeMark
+ CreateNodes(nodenum);
+ CreateEdges(edgenum);
+ } // vf_Graph
/**
- * Gets a graph node mark.
- * @param node_num a node number
- * @return a graph node mark
+ * Control flow graph destructor.
+ * @note Function release memory for graph structure, nodes and edges.
*/
- int GetNodeMark(unsigned node_num)
- {
- return GetNode(node_num)->m_mark;
- } // GetNodeMark
+ ~vf_Graph() {
+ if (m_free) {
+ vf_delete_pool(m_pool);
+ }
+ } // ~vf_Graph
/**
- * Checks if a node is marked.
- * @param node_num a graph node number
- * @return true if node is marked, false otherwise
+ * Allocates memory for graph nodes.
+ * @param count a number of nodes
*/
- bool IsNodeMarked(unsigned node_num)
+ void CreateNodes(unsigned count)
{
- return 0 != GetNode(node_num)->m_mark;
- } // IsNodeMarked
+ assert(count > 0);
+ vf_NodeContainer *nodes =
+ (vf_NodeContainer *) AllocMemory(sizeof(vf_NodeContainer)
+ + (count - 1) * sizeof(vf_Node));
+
+ nodes->container.m_max = count;
+ if (m_nodes == NULL) {
+ m_nodes = nodes;
+ } else {
+ vf_add_container(&m_nodes->container, &nodes->container);
+ }
+ }
/**
- * Function removes node mark.
+ * Allocates a container for graph edges.
+ * @param count a number of edges
*/
- void CleanNodesMark()
+ void CreateEdges(unsigned count)
{
- // clean node's mark
- assert(m_nodes);
- vf_NodeContainer *nodes = m_nodes;
- while (nodes != NULL) {
- for (unsigned index = 0; index < nodes->m_used; index++) {
- nodes->m_node[index].m_mark = 0;
- }
- nodes = nodes->m_next;
+ assert(count > 0);
+ vf_EdgeContainer *edges =
+ (vf_EdgeContainer *) AllocMemory(sizeof(vf_EdgeContainer)
+ + (count - 1) * sizeof(vf_Edge));
+ edges->container.m_max = count;
+ if (m_edges == NULL) {
+ m_edges = edges;
+ } else {
+ vf_add_container(&m_edges->container, &edges->container);
}
- return;
- } // CleanNodesMark
+ }
/**
- * Sets local variable reference initialization flag for a anode.
- * @param node_num a graph node number
- * @param flag a node flag
+ * Gets a graph node.
+ * @param[in] node_num a node number, should be in range
+ * @return a handle of the node
*/
- void SetNodeInitFlag(unsigned node_num, bool flag)
+ vf_NodeHandle GetNode(unsigned node_num) const
{
- vf_Node *node = (vf_Node *) GetNode(node_num);
- node->m_initialized = flag;
- } // SetNodeInitFlag
+ // get node
+ assert(m_nodes);
+ assert(node_num < m_nodenum);
+
+ vf_NodeContainer *nodes =
+ (vf_NodeContainer *) vf_get_container(&m_nodes->container,
+ node_num);
+ return nodes->m_node + node_num;
+ } // GetNode
+
/**
- * Gets an initialization flag for local variable reference for a given node.
- * @param node_num a graph node number
- * @return true if the local variable reference has
- * to be initialized, false otherwise.
+ * Gets a graph node from a program counter.
+ *
+ * @param[in] pc a bytecode index at a node start
+ * @return a handle of a node
*/
- bool GetNodeInitFlag(unsigned node_num)
+ vf_NodeHandle GetNodeFromBytecodeIndex(unsigned pc) const
{
- return GetNode(node_num)->m_initialized;
- } // GetNodeInitFlag
+ vf_InstrHandle instr = m_ctx->m_bc[pc].m_instr;
+ assert(instr);
+ assert(m_ctx->m_bc[pc].m_instr->m_addr - m_ctx->m_bytes == pc);
+ vf_NodeHandle node = instr->m_node;
+ assert(GetNodeNum(node) > m_ctx->m_handlers);
+ return node;
+ }
/**
- * Function creates IN data flow vector of a node.
- * @param node_num a graph node number
- * @param example a handle of copied data flow vector
- * @param need_copy a copy flag
- * @note If copy flag true, incoming vector is copied to IN,
- * else if copy flag false, IN vector is created
- * with parameters of current vector.
+ * Gets the start node.
+ * @return the handle of the start node
*/
- void SetNodeInVector(unsigned node_num,
- vf_MapVectorHandle example, bool need_copy)
+ vf_NodeHandle GetStartNode()
{
- SetVector(GetNodeInVector(node_num), example, need_copy);
- } // SetNodeInVector
+ return m_nodes->m_node;
+ } // GetStartNode
/**
- * Creates OUT data flow vector of a node.
- * @param node_num a graph node number
- * @param example a handle of copied data flow vector
- * @param need_copy a copy flag
- * @note If copy flag true, incoming vector is copied to OUT,
- * else if copy flag false, OUT vector is created
- * with parameters of current vector.
+ * Adds the end node.
+ * @return the handle of the end node
*/
- void SetNodeOutVector(unsigned node_num,
- vf_MapVectorHandle example, bool need_copy)
+ vf_NodeHandle AddEndNode()
{
- SetVector(GetNodeOutVector(node_num), example, need_copy);
- } // SetNodeOutVector
+ m_endnode = NewNode(VF_NODE_END_ENTRY);
+ return m_endnode;
+ } // GetEndNode
/**
- * Gets IN data flow vector for the node.
- * @param node_num graph node number
- * @return a reference to IN data flow stack map vector
- * @note Assertion is raised if node_num is out of range.
- * @see vf_MapVector_t
+ * Gets the end node.
+ * @return the handle of the end node
*/
- vf_MapVectorHandle GetNodeInVector(unsigned node_num)
+ vf_NodeHandle GetEndNode()
{
- return &(GetNode(node_num)->m_inMapVector);
- } // GetNodeInVector
+ return m_endnode;
+ } // GetEndNode
/**
- * Gets OUT data flow vector for the node.
- * @param node_num graph node number
- * @return a reference to OUT data flow stack map vector
- * @see vf_MapVector_t
+ * Creates a new node of a specific type.
+ * A node array must have enough free space for a new element.
+ * @param[in] type node type
+ * @return a handle of the created node
*/
- vf_MapVectorHandle GetNodeOutVector(unsigned node_num)
+ vf_NodeHandle NewNode(vf_NodeType type)
{
- return &(GetNode(node_num)->m_outMapVector);
- } // GetNodeOutVector
+ // get node
+ assert(m_nodes);
+ unsigned count = m_nodenum;
+ vf_NodeContainer *nodes =
+ (vf_NodeContainer *) vf_get_container(&m_nodes->container, count);
+
+ // increment nodes count
+ m_nodenum++;
+ nodes->container.m_used++;
+ assert(nodes->container.m_used <= nodes->container.m_max);
+
+ // set node
+ vf_Node *node = nodes->m_node + count;
+ node->m_type = type;
+ return node;
+ } // NewNode
+
/**
- * Function creates graph edges.
- * @param number - number of edges
+ * Creates a new node for a bytecode range.
+ * A node array must have enough free space for a new element.
+ * @param[in] start the first instruction
+ * @param[in] end the last instruction
+ * @return a handle of the created node
*/
- void CreateEdges(unsigned number);
+ vf_NodeHandle NewNode(vf_InstrHandle start, vf_InstrHandle end)
+ {
+ // get node
+ vf_Node *node = (vf_Node *) NewNode(VF_NODE_CODE_RANGE);
+ node->m_start = start;
+ node->m_end = end;
+ return node;
+ } // NewNode(start, end)
/**
- * Function receives next IN edge of graph node.
- * @param edge_num - number of graph edge
- * @return Number of next IN edge of node.
- * @note Assertion is raised if edge_num is out of range.
+ * Copies a node from existing node.
+ * A node array must have enough free space for a new element.
+ * @param[in] node a handle of an existing node
+ * @return a handle of the created node
*/
- unsigned GetEdgeNextInEdge(unsigned edge_num)
+ vf_NodeHandle NewNode(vf_NodeHandle node)
{
- return GetEdge(edge_num)->m_innext;
- } // GetEdgeNextInEdge
+ // get node
+ vf_Node *new_node = (vf_Node *) NewNode(node->m_type);
+ *new_node = *node;
+ // edges are outdated, delete them
+ new_node->m_inedge = new_node->m_outedge = NULL;
+ new_node->m_outnum = 0;
+ return new_node;
+ } // NewNode(vf_NodeHandle node)
/**
- * Function receives next OUT edge of graph node.
- * @param edge_num - number of graph edge
- * @return Number of next OUT edge of node.
- * @note Assertion is raised if edge_num is out of range.
+ * Creates a new edge between graph nodes.
+ *
+ * @param start_node an edge start
+ * @param end_node an edge end
+ * @return a handle of a created edge
*/
- unsigned GetEdgeNextOutEdge(unsigned edge_num)
+ vf_EdgeHandle NewEdge(vf_Node *start_node, vf_Node *end_node)
{
- return GetEdge(edge_num)->m_outnext;
- } // GetEdgeNextOutEdge
+ // get edge
+ assert(m_edges);
+
+ VF_TRACE("graph",
+ "Creating a new edge from " << GetNodeNum(start_node)
+ << " to " << GetNodeNum(end_node));
+ unsigned count = m_edgenum;
+ vf_EdgeContainer *edges =
+ (vf_EdgeContainer *) vf_get_container(&m_edges->container, count);
+
+ // get a new edge and edge's nodes
+ vf_Edge *edge = edges->m_edge + count;
+
+ // set a new edge
+ edge->m_start = start_node;
+ edge->m_end = end_node;
+ edge->m_outnext = start_node->m_outedge;
+ start_node->m_outedge = edge;
+ start_node->m_outnum++;
+ edge->m_innext = end_node->m_inedge;
+ end_node->m_inedge = edge;
+
+ // increment edge count
+ m_edgenum++;
+ edges->container.m_used++;
+ assert(edges->container.m_used <= edges->container.m_max);
+ return edge;
+ } // NewEdge
/**
- * Function receives start graph node of edge.
- * @param edge_num - number of graph edge
- * @return Number start graph node of edge.
- * @note Assertion is raised if edge_num is out of range.
+ * Resets an internal graph node iterator.
*/
- unsigned GetEdgeStartNode(unsigned edge_num)
+ void ResetNodeIterator()
{
- return GetEdge(edge_num)->m_start;
- } // GetEdgeStartNode
+ iterator.Reset(&m_nodes->container);
+ }
/**
- * Function receives end graph node of edge.
- * @param edge_num - number of graph edge
- * @return Number end graph node of edge.
- * @note Assertion is raised if edge_num is out of range.
+ * Gets a next node.
*/
- unsigned GetEdgeEndNode(unsigned edge_num)
+ vf_NodeHandle GetNextNode()
{
- return GetEdge(edge_num)->m_end;
- } // GetEdgeStartNode
+ return iterator.GetNextNode();
+ }
/**
- * Function receives number of IN edges of graph node.
- * @param node_num - number of graph node
- * @return Number of IN edges of graph node.
- * @note Assertion is raised if node_num is out of range.
+ * Checks if there are still elements to iterate.
*/
- unsigned GetNodeInEdgeNumber(unsigned node_num)
+ bool HasMoreElements() const
{
- return GetNode(node_num)->m_innum;
- } // GetNodeInEdgeNumber
+ return iterator.HasMoreElements();
+ }
/**
- * Function receives number of OUT edges of graph node.
- * @param node_num - number of graph node
- * @return Number of OUT edges of graph node.
- * @note Assertion is raised if node_num is out of range.
+ * Counts graph nodes.
+ * @return a number of graph nodes
*/
- unsigned GetNodeOutEdgeNumber(unsigned node_num)
+ unsigned GetNodeCount()
{
- return GetNode(node_num)->m_outnum;
- } // GetNodeOutEdgeNumber
+ return m_nodenum;
+ } // GetNodeCount
/**
- * Function receives first IN edge of graph node.
- * @param node_num - number of graph node
- * @return First IN edges of node.
- * @note Assertion is raised if node_num is out of range.
+ * Counts graph edges excluding
+ * the reserved edge.
+ * @return a number of graph edges
*/
- unsigned GetNodeFirstInEdge(unsigned node_num)
+ unsigned GetEdgeCount() const
{
- return GetNode(node_num)->m_inedge;
- } // GetNodeFirstInEdge
+ return m_edgenum;
+ } // GetEdgeCount
/**
- * Function receives first OUT edge of graph node.
- * @param node_num - number of graph node
- * @return First OUT edges of node.
- * @note Assertion is raised if node_num is out of range.
+ * Removes marks for all nodes.
*/
- unsigned GetNodeFirstOutEdge(unsigned node_num)
+ void CleanNodeMarks()
{
- return GetNode(node_num)->m_outedge;
- } // GetNodeFirstOutEdge
+ assert(m_nodes);
+ ResetNodeIterator();
+
+ // clean node marks
+ while (HasMoreElements()) {
+ ((vf_Node *) GetNextNode())->m_mark = 0;
+ }
+ } // CleanNodeMarks
/**
* Allocates memory from the graph memory pool.
@@ -553,199 +650,272 @@ class vf_Graph
void *AllocMemory(unsigned size)
{
assert(size);
- return vf_alloc_pool_memory(m_pool, size);
+ return vf_palloc(m_pool, size);
} // AllocMemory
/**
- * Function cleans graph node enumeration, creates new graph
- * enumeration structure and sets first enumeration element.
- * @param node_num - first enumeration node
- * @note Assertion is raised if node_num is out of range.
+ * Allocates a graph node enumeration sequence and
+ * sets first enumeration element.
+ * @param node a first enumeration node
*/
- void SetStartCountNode(unsigned node_num);
+ void SetStartCountNode(vf_Node *node)
+ {
+ // check node number is in range
+ assert(m_nodes);
+ assert(node);
+
+ // allocate memory
+ m_enum = (vf_NodeHandle *) vf_palloc(m_pool, sizeof(vf_NodeHandle)
+ * m_nodenum);
+
+ // clean node enumeration
+ ResetNodeIterator();
+ while (HasMoreElements()) {
+ ((vf_Node *) GetNextNode())->m_nodecount = ALL_BITS_SET;
+ }
+
+ // set node enumeration number
+ node->m_nodecount = 0;
+
+ // set enumeration first element;
+ m_enum[0] = node;
+ m_enumcount = 1;
+ }
/**
- * Function receives number of enumerated nodes.
+ * Receives number of enumerated nodes.
* @return Function returns number of enumerated nodes.
*/
- unsigned GetEnumCount()
+ unsigned GetReachableNodeCount()
{
return m_enumcount;
} // SetStartCountNode
/**
- * Function sets next enumeration element in graph enumeration structure.
- * @param node_num - next enumeration node
- * @note Assertion is raised if node_num is out of range.
+ * Sets a next enumeration element in a graph enumeration
+ * and stores the index in the node.
+ * @param node a node handle
*/
- void SetNextCountNode(unsigned node_num)
+ void AddReachableNode(vf_Node *node)
{
// check enumeration count is in range
assert(m_enumcount < m_nodenum);
// set enumeration element for node
- m_enum[m_enumcount] = node_num;
+ m_enum[m_enumcount] = node;
// set node enumeration number and increase number of enumerated nodes
- vf_Node *node = (vf_Node *) GetNode(node_num);
node->m_nodecount = m_enumcount++;
- return;
} // SetNextCountNode
/**
- * Function receives first enumerated graph node.
- * @return First enumerated graph node in graph enumeration structure.
+ * Suits for counting reachable nodes.
+ * @param node a node handle
*/
- unsigned GetStartCountNode()
+ void IncrementReachableCount()
{
- return m_enum[0];
- } // GetStartCountNode
+ m_enumcount++;
+ } // IncreaseReachableCount
/**
- * Function receives graph node relevant to enumeration element.
- * @param count - given enumeration element
- * @return Graph node relevant to enumeration element.
- * @note Assertion is raised if count is out of range.
+ * Gets a graph node by enumeration index.
+ * @param count given enumeration index
+ * @return a graph node handle
*/
- unsigned GetCountElementNode(unsigned count)
+ vf_NodeHandle GetReachableNode(unsigned count)
{
- // check element is in range.
- assert(count < m_nodenum);
return m_enum[count];
} // GetCountElementNode
/**
- * Function receives graph node enumeration count.
- * @param node_num - given node
- * @return Graph node enumeration count.
- * @note Assertion is raised if node_num is out of range.
+ * Copies a data flow vector from a given source.
+ * @param source a handle of a source vector
+ * @param dest a pointer to a vector to set
*/
- unsigned GetNodeCountElement(unsigned node_num)
+ void CopyVector(vf_MapVectorHandle source, vf_MapVector *dest)
{
- return GetNode(node_num)->m_nodecount;
- } // GetNodeCountElement
+ assert(AreMapsAllocated(source));
+ assert(AreMapsAllocated(dest));
- /**
- * Function prints graph structure in stderr.
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @see vf_Context_t
- */
- void DumpGraph(vf_Context_t * context);
+ dest->m_number = source->m_number;
+ dest->m_depth = source->m_depth;
+
+ unsigned index;
+ for (index = 0; index < source->m_number; index++) {
+ dest->m_local[index] = source->m_local[index];
+ }
+ for (index = 0; index < source->m_depth; index++) {
+ dest->m_stack[index] = source->m_stack[index];
+ }
+ }
/**
- * Function dumps verifier graph in file in DOT format.
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @note File name is created from class and method names with .dot extension.
- * @see vf_Context_t
+ * Copies a data flow vector from a given source,
+ * nullifies the rest of the destination.
+ * @param source a handle of a source vector
+ * @param dest a pointer to a vector to set
*/
- void DumpDotGraph(vf_Context_t * context);
+ void CopyFullVector(vf_MapVectorHandle source, vf_MapVector *dest)
+ {
+ assert(AreMapsAllocated(source));
+ assert(AreMapsAllocated(dest));
- private:
- vf_NodeContainer *m_nodes; ///< array of nodes
- vf_EdgeContainer *m_edges; ///< array of edges
- vf_VerifyPool_t *m_pool; ///< graph memory pool
- unsigned *m_enum; ///< graph node enumeration structure
- unsigned m_nodenum; ///< number of nodes
- unsigned m_edgenum; ///< number of edges
- unsigned m_enummax; ///< max number of enumerated elements
- unsigned m_enumcount; ///< number of enumerated elements
- bool m_free; ///< need to free pool
+ unsigned index;
+ vf_MapEntry zero = { 0 };
- /**
- * Creates a data flow vector from a given example.
- * @param vector_handle a vector to set
- * @param example a handle of an example vector
- * @param need_copy a copy flag
- * @note If copy flag true, incoming vector is copied to,
- * otherwise IN vector is created
- * with parameters of current vector.
- */
- void SetVector(vf_MapVectorHandle vector_handle,
- vf_MapVectorHandle example, bool need_copy);
+ dest->m_number = source->m_number;
+ dest->m_depth = source->m_depth;
+
+ // copy locals
+ for (index = 0; index < source->m_number; index++) {
+ dest->m_local[index] = source->m_local[index];
+ }
+ for (; index < m_ctx->m_maxlocal; index++) {
+ dest->m_local[index] = zero;
+ }
+ // copy stack
+ for (index = 0; index < source->m_depth; index++) {
+ dest->m_stack[index] = source->m_stack[index];
+ }
+ for (; index < m_ctx->m_maxstack; index++) {
+ dest->m_stack[index] = zero;
+ }
+ }
/**
- * Function prints graph node in stderr.
- * @param node_num - number of graph node
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @note Assertion is raised if node_num is out of range.
- * @see vf_Context_t
+ * Allocates a vector with maximum storage capacity.
+ * @param[out] vector map to allocate
*/
- void DumpNode(unsigned node_num, vf_Context_t * context);
+ void AllocVector(vf_MapVector *vector)
+ {
+ // create and set local vector
+ if (m_ctx->m_maxlocal && !vector->m_local) {
+ vector->m_local =
+ (vf_MapEntry *) vf_palloc(m_pool,
+ m_ctx->m_maxlocal * sizeof(vf_MapEntry));
+ }
+ // create and set stack vector
+ if (m_ctx->m_maxstack && !vector->m_stack) {
+ vector->m_stack =
+ (vf_MapEntry *) vf_palloc(m_pool,
+ m_ctx->m_maxstack * sizeof(vf_MapEntry));
+ }
+ }
/**
- * Function prints graph node instruction in stream.
- * @param node_num - number of graph node
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @note Assertion is raised if node_num is out of range.
- * @see vf_Context_t
+ * Prints a graph structure in stderr.
+ * @note Empty in release mode.
*/
- void DumpNodeInternal(unsigned node_num, vf_Context_t * context);
-
+ void DumpGraph();
/**
- * Function dumps graph header in file in DOT format.
- * @param graph_name - graph name
- * @param fout - file stream
- * @note Function is valid in debug mode.
- * @note Graph name is created from class and method names.
+ * Dumps a graph in a file in DOT format.
+ * @note Empty in release mode.
+ * @note File name is created from class and method names with .dot extension.
*/
- void DumpDotHeader(char *graph_name, ofstream &fout);
+ void DumpDotGraph();
+#if _VF_DEBUG
/**
- * Function dumps graph node in file in DOT format.
- * @param node_num - number of graph node
- * @param fout - file stream
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @note Assertion is raised if node_num is out of range.
- * @see vf_Context_t
+ * Gets a graph node number for debugging purposes.
+ *
+ * @param[in] node a node handle
+ * @return a subsequent node number
*/
- void DumpDotNode(unsigned node_num, ofstream &fout,
- vf_Context_t * context);
+ unsigned GetNodeNum(vf_NodeHandle node) const
+ {
+ assert(node);
+ unsigned node_num = 0;
+ vf_NodeContainer *nodes = m_nodes;
+ while (nodes) {
+ unsigned index = node - nodes->m_node;
+ if (index < nodes->container.m_max) {
+ node_num += index;
+ assert(node_num < m_nodenum);
+ return node_num;
+ }
+ node_num += nodes->container.m_max;
+ nodes = (vf_NodeContainer *) nodes->container.m_next;
+ }
+ VF_DIE("vf_Graph::GetNodeNum: cannot find a node " << node);
+ return 0;
+ }
/**
- * Function dumps graph node instruction in file stream in DOT format.
- * @param node_num - number of graph node
- * @param next_node - separator between nodes in stream
- * @param next_instr - separator between instructions in stream
- * @param fout - output file stream
- * @param context - current verifier context
- * @note Function is valid in debug mode.
- * @note Assertion is raised if node_num is out of range.
- * @see vf_Context_t
+ * Checks amount of pre-allocated space for nodes in the graph.
*/
- void DumpDotNodeInternal(unsigned node_num,
- char *next_node,
- char *next_instr, ofstream &fout, vf_Context_t * context);
+ unsigned HasMoreNodeSpace() const
+ {
+ unsigned used = vf_used_space(&m_nodes->container);
+ assert(used == m_nodenum);
+ return vf_total_space(&m_nodes->container) - used;
+ } // HasMoreNodeSpace
/**
- * Function dumps graph end in file in DOT format.
- * @param fout - output file stream
- * @note Function is valid in debug mode.
+ * Checks amount of pre-allocated space for edges in the graph.
*/
- void DumpDotEnd(ofstream &fout);
+ unsigned HasMoreEdgeSpace() const
+ {
+ unsigned used = vf_used_space(&m_edges->container);
+ assert(used == m_edgenum);
+ return vf_total_space(&m_edges->container) - used;
+ } // HasMoreEdgeSpace
+
+#endif // _VF_DEBUG
}; // vf_Graph
/**
- * Checks if a code range node ends with a specific
- * instruction type.
- *
- * @param[in] context a verifier context
- * @param[in] node_index the node identifier
- *
- * @return a type of the last instruction of code range node
- */
-static inline vf_CodeType
-vf_get_last_instruction_type(vf_ContextHandle context, unsigned node_index)
-{
- vf_NodeHandle node = context->m_graph->GetNode(node_index);
- assert(VF_TYPE_NODE_CODE_RANGE == node->m_type);
- return context->m_code[node->m_end].m_type;
+ * Checks if a given edge is a subroutine call branch.
+ * @param[in] edge an edge handle
+ * @param[in] ctx a verification context
+ * @return true if this branch is a jsr call branch
+ */
+static inline bool vf_is_jsr_branch(vf_EdgeHandle edge, vf_ContextHandle ctx)
+{
+ vf_NodeHandle node = edge->m_start;
+ return (VF_NODE_CODE_RANGE == node->m_type)
+ && (VF_INSTR_JSR == node->m_end->m_type)
+ && (VF_NODE_CODE_RANGE == edge->m_end->m_type);
}
+
+/**
+ * Gets a subroutine number for a node. The function is slow and should be used for
+ * debugging purposes only.
+ * @param[in] sub a given subroutine handle
+ * @param[in] ctx a verification context
+ * @return a sequential subroutine number in a list
+ */
+unsigned vf_get_sub_num(vf_SubHandle sub, vf_ContextHandle ctx);
+
+/**
+ * Checks that a stack depth is the same as during last visit, calculates
+ * a stack modifier, counts a number of visited nodes, for each instruction checks
+ * that stack doesn't overflow.
+ * @param[in, out] node a pointer to a node structure, m_mark is
+ * modified during the call
+ * @param[in, out] depth starts as node depth before the first node instruction and ends
+ * as a node depth after the last node instruction
+ * @param[in] ctx a verifier context
+ * @return VER_Continue if this node wasn't visited before, and analysis of
+ * subsequent nodes is needed, VER_OK if the stack depth is consistent, an
+ * error code otherwise
+ */
+vf_Result vf_check_node_stack_depth(vf_Node *node, // a graph node
+ unsigned &depth, // stack depth
+ vf_Context *ctx); // verification context
+
+/**
+ * Creates and sets graph node OUT vector.
+ * @param[in] node a graph node handle
+ * @param[in, out] invector an IN vector, then OUT vector
+ * @param[in] ctx a verifier context
+ * @return VER_OK if OUT vector wasn't changed,
+ * VER_Continue
+ * if the vector was changed successfully, an error code otherwise
+ */
+vf_Result
+vf_set_node_out_vector(vf_NodeHandle node,
+ vf_MapVector *invector, vf_Context *ctx);
#endif // _VERIFIER_GRAPH_H_
diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\ver_real.h 91/trunk/working_vm/vm/vmcore/src/verifier\ver_real.h
--- 9/trunk/working_vm/vm/vmcore/src/verifier\ver_real.h Tue Mar 20 19:34:51 2007
+++ 91/trunk/working_vm/vm/vmcore/src/verifier\ver_real.h Tue Apr 03 19:59:02 2007
@@ -45,55 +45,97 @@ using namespace std;
*/
//===========================================================
/**
- * Define debug mode for verifier.
+ * Defines a debug mode for verifier.
*/
#ifdef NDEBUG
-#define _VERIFY_DEBUG 0
+#define _VF_DEBUG 0
#else // NDEBUG
-#define _VERIFY_DEBUG 1
+#define _VF_DEBUG 1
#endif // NDEBUG
/**
- * Debugging and trace message defines.
- * @note Debug messages is available only in debug mode,
- * trace messages is available in any mode.
- * @note Verifier trace looks like: 'verifier' + component of verifier
- */
-#if _VERIFY_DEBUG
-#define VERIFY_DEBUG(info) ECHO("vf_debug: " << info)
-#else // _VERIFY_DEBUG
-#define VERIFY_DEBUG(info)
-#endif // _VERIFY_DEBUG
-#define VERIFY_TRACE(comp, mess) TRACE2("verifier." comp, mess)
-#define VERIFY_REPORT(context, error_message ) \
- { \
- stringstream stream; \
- stream << error_message; \
- vf_set_error_message( stream, (context) ); \
- }
-#define VERIFY_REPORT_CLASS(context, method, error_message ) \
- VERIFY_REPORT(context, \
- "(class: " << class_get_name( (context)->m_class ) \
- << ", method: " << method_get_name( method ) \
- << method_get_descriptor( method ) \
- << ") " << error_message )
-#define VERIFY_REPORT_METHOD(context, error_message ) \
- VERIFY_REPORT_CLASS(context, (context)->m_method, error_message )
+ * Both debug and trace channels are available only at debug mode.
+ * A debug channel is visible for a user while a trace channel should be
+ * enabled via -Xtrace:verifier command line option.
+ */
+#if _VF_DEBUG
+#define VF_DEBUG( info ) ECHO( "vf_debug: " << info )
+#define VF_DUMP( category, expr ) { \
+ static LogSite logSite = { UNKNOWN, NULL }; \
+ if( logSite.state && is_trace_enabled( "vfdump." category, &logSite ) ) { \
+ expr; \
+ } \
+}
+#define VF_STOP assert(0)
+#else
+#define VF_DEBUG(info)
+#define VF_DUMP(category, expr)
+#define VF_STOP DIE("Aborted at " __FILE__ "(" << __LINE__ << ")")
+#endif // _VF_DEBUG
+
+#define VF_TRACE(comp, message) TRACE2("verifier." comp, message)
+/**
+ * Verifer dump domains. They can be specified in a command line in
+ * a following form -Xtrace:vfdump.<domain>.
+ */
+/** Type constraints for a class. */
+#define DUMP_CONSTRAINT "constraint"
+/** An instruction array. */
+#define DUMP_INSTR "instr"
+/** A control flow graph. */
+#define DUMP_GRAPH "graph"
+/** A graph with cleaned dead nodes and inlined subroutines. */
+#define DUMP_MOD "mod_graph"
+/** A graph in a dot format. */
+#define DUMP_DOT "dot"
+/** A modified graph in a dot format. */
+#define DUMP_DOT_MOD "mod_dot"
+/** Node map vectors. */
+#define DUMP_NODE_MAP "map.node"
+/** Instruction map vectors. */
+#define DUMP_INSTR_MAP "map.instr"
+/** Merged map vectors. */
+#define DUMP_MERGE_MAP "map.merge"
+/** A path to subroutine ret instruction. */
+#define DUMP_NODESTACK "node.stack"
+
+
+/** Store a verification error in a verification context. */
+#define VF_SET_CTX( ctx, error_message ) \
+{ \
+ stringstream stream; \
+ stream << error_message; \
+ vf_set_error_message( stream, ( ctx ) ); \
+}
+
+/** Dump a current class and method. */
+#define VF_REPORT_CTX( ctx ) "(class: " << class_get_name( (ctx)->m_class ) \
+ << ", method: " << method_get_name( (ctx)->m_method ) \
+ << method_get_descriptor( (ctx)->m_method ) << ") "
+
+/** Report a verification error. */
+#define VF_REPORT( ctx, error_message ) \
+ VF_SET_CTX( ctx, VF_REPORT_CTX( ctx ) << error_message )
+
+/** Abort a verifier abnormally. */
+#define VF_DIE( error_message ) \
+ VF_DEBUG( "Verifer aborted: " << error_message ); \
+ VF_STOP;
/**
* Define source code line and source file name parameters and arguments.
*/
-#if _VERIFY_DEBUG
-#define VERIFY_SOURCE_PARAMS UNREF int line_, UNREF const char *file_
-#define VERIFY_SOURCE_ARGS0 __LINE__, __FILE__
-#define VERIFY_SOURCE_ARGS1 line_, file_
-#define VERIFY_REPORT_SOURCE file_ << "(" << line_ << "): "
-#else // _VERIFY_DEBUG
-#define VERIFY_SOURCE_PARAMS int
-#define VERIFY_SOURCE_ARGS0 0
-#define VERIFY_SOURCE_ARGS1 0
-#define VERIFY_REPORT_SOURCE ""
-#endif // _VERIFY_DEBUG
+#if _VF_DEBUG
+#define VF_SOURCE_PARAMS UNREF int line_, UNREF const char *file_
+#define VF_SOURCE_ARGS0 __LINE__, __FILE__
+#define VF_SOURCE_ARGS1 line_, file_
+#define VF_REPORT_SOURCE file_ << "(" << line_ << "): "
+#else // _VF_DEBUG
+#define VF_SOURCE_PARAMS int
+#define VF_SOURCE_ARGS0 0
+#define VF_SOURCE_ARGS1 0
+#define VF_REPORT_SOURCE ""
+#endif // _VF_DEBUG
//===========================================================
// Verifier contant pool checks
@@ -103,64 +145,64 @@ using namespace std;
* Constant pool checks.
*/
// for handler id = 0 is legal value
-#define CHECK_HANDLER_CONST_POOL_ID( id, len, context ) \
- if( (id) >= (len) ) { \
- VERIFY_REPORT_METHOD( context, "Illegal constant pool index in handler" ); \
- return VER_ErrorHandler; \
+#define CHECK_HANDLER_CONST_POOL_ID( id, len, ctx ) \
+ if( (id) >= (len) ) { \
+ VF_REPORT( ctx, "Illegal constant pool index in handler" ); \
+ return VER_ErrorHandler; \
}
// for handler id = 0 is legal value
-#define CHECK_HANDLER_CONST_POOL_CLASS( context, id ) \
- if( (id) && class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_Class ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool for handler, " \
- << id << ": CONSTANT_Class is expected" ); \
- return VER_ErrorHandler; \
+#define CHECK_HANDLER_CONST_POOL_CLASS( ctx, id ) \
+ if( (id) && class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_Class ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool for handler, " \
+ << id << ": CONSTANT_Class is expected" ); \
+ return VER_ErrorHandler; \
}
-#define CHECK_CONST_POOL_ID( id, len, context ) \
- if( !(id) || (id) >= (len) ) { \
- VERIFY_REPORT_METHOD( context, "Illegal constant pool index" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_ID( id, len, ctx ) \
+ if( !(id) || (id) >= (len) ) { \
+ VF_REPORT( ctx, "Illegal constant pool index" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_CLASS( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_Class ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_Class is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_CLASS( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_Class ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_Class is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_METHOD( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_Methodref ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_Methodref is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_METHOD( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_Methodref ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_Methodref is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_INTERFACE( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_InterfaceMethodref ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_InterfaceMethodref is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_INTERFACE( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_InterfaceMethodref ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_InterfaceMethodref is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_FIELD( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_Fieldref ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_Fieldref is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_FIELD( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_Fieldref ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_Fieldref is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_TYPE( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_NameAndType ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_NameAndType is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_TYPE( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_NameAndType ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_NameAndType is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_STRING( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_String ) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_String is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_STRING( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_String ) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_String is expected" ); \
+ return VER_ErrorConstantPool; \
}
-#define CHECK_CONST_POOL_UTF8( context, id ) \
- if( class_get_cp_tag( (context)->m_class, (id) ) != _CONSTANT_Utf8) { \
- VERIFY_REPORT_METHOD( context, "Illegal type in constant pool, " \
- << id << ": CONSTANT_Utf8 is expected" ); \
- return VER_ErrorConstantPool; \
+#define CHECK_CONST_POOL_UTF8( ctx, id ) \
+ if( class_get_cp_tag( (ctx)->m_class, (id) ) != _CONSTANT_Utf8) { \
+ VF_REPORT( ctx, "Illegal type in constant pool, " \
+ << id << ": CONSTANT_Utf8 is expected" ); \
+ return VER_ErrorConstantPool; \
}
//===========================================================
@@ -168,6 +210,11 @@ using namespace std;
//===========================================================
/**
+ * Verifier error codes.
+ */
+typedef Verifier_Result vf_Result;
+
+/**
* Constraint check types enum.
*/
typedef enum
@@ -187,7 +234,7 @@ typedef enum
VF_CHECK_INVOKESPECIAL,
VF_CHECK_UNINITIALIZED_THIS,
VF_CHECK_NUM
-} vf_CheckConstraint_t;
+} vf_CheckConstraint;
/**
* Stack map entry types enum.
@@ -208,29 +255,29 @@ typedef enum
SM_DOUBLE_HI,
SM_RETURN_ADDR,
// additional types
+ SM_ANY, // matches any value
SM_COPY_0,
SM_COPY_1,
SM_COPY_2,
SM_COPY_3,
SM_UP_ARRAY,
- SM_RETURN,
- SM_TERMINATE,
SM_WORD,
SM_WORD2_LO,
SM_WORD2_HI,
SM_NUMBER
-} vf_MapType_t;
+} vf_MapType;
/**
* Each instruction has a descriptive bitmap.
*/
typedef enum
{
- VF_TYPE_INSTR_NONE = 0,
- VF_TYPE_INSTR_RETURN = 1,
- VF_TYPE_INSTR_THROW = 2,
- VF_TYPE_INSTR_SUBROUTINE = 3
-} vf_CodeType;
+ VF_INSTR_NONE = 0,
+ VF_INSTR_RETURN = 1,
+ VF_INSTR_THROW = 2,
+ VF_INSTR_JSR = 3,
+ VF_INSTR_RET = 4
+} vf_InstrType;
//===========================================================
// Verifier predefined structures
@@ -238,37 +285,147 @@ typedef enum
/**
* @ingroup Handles
- * The handle of the verifier context.
+ * A handle of a verifier context.
*/
typedef const struct vf_Context *vf_ContextHandle;
+/**
+ * @ingroup Handles
+ * A handle of a subroutine information.
+ */
+typedef const struct vf_SubContext *vf_SubContextHandle;
+/**
+ * @ingroup Handles
+ * A graph handle.
+ */
+typedef const class vf_Graph *vf_GraphHandle;
+/**
+ * @ingroup Handles
+ * A handle of a graph node.
+ */
+typedef const struct vf_Node *vf_NodeHandle;
+/**
+ * @ingroup Handles
+ * A map vector handle.
+ */
+typedef const struct vf_MapVector *vf_MapVectorHandle;
+/**
+ * @ingroup Handles
+ * A handle of an instruction.
+ */
+typedef const struct vf_Instr *vf_InstrHandle;
+
+//===========================================================
+// Code instruction structures.
+//===========================================================
+
+/**
+ * Valid types structure.
+ */
+struct vf_ValidType
+{
+ unsigned number; ///< number of types
+ const char *string[1]; ///< type array
+};
+
+/**
+ * Stack map entry structure.
+ */
+struct vf_MapEntry
+{
+ vf_ValidType *m_vtype; ///< valid type for reference
+ union
+ {
+ unsigned m_new; ///< program count of opcode new for uninitialized
+ unsigned m_pc; ///< program count of return address for subroutine
+ };
+ union
+ {
+ unsigned short m_local; ///< number of local variable
+ unsigned short m_index; ///< constant pool index for access check
+ };
+ unsigned short m_type:5; ///< stack map type @see vf_MapType
+ unsigned short m_ctype:4; ///< constraint type @see vf_CheckConstraint
+ unsigned short m_is_local:1; ///< local variable modify flag
+ ///< true - modify local, false - modify stack
+};
-/// Verifier context structure.
-typedef struct vf_Context vf_Context_t;
-/// Verifier structure for a byte of a bytecode.
-typedef struct vf_BCode vf_BCode_t;
-/// Verifier valid types structure.
-typedef struct vf_ValidType vf_ValidType_t;
-/// Verifier stack map entry structure.
-typedef struct vf_MapEntry vf_MapEntry_t;
-/// Verifier code instruction structure.
-typedef struct vf_Code vf_Code_t;
-/// Verifier constant pool parse structure.
-typedef union vf_Parse vf_Parse_t;
-/// Verifier graph structure declaration.
-class vf_Graph;
-/// Verifier type constraint structure.
-typedef struct vf_TypeConstraint vf_TypeConstraint_t;
-/// Verifier hash table structure.
-typedef struct vf_Hash vf_Hash_t;
-/// Verifier hash table entry structure.
-typedef struct vf_HashEntry vf_HashEntry_t;
-/// Verifier pool structure.
-typedef struct vf_VerifyPool vf_VerifyPool_t;
-/// Verifier pool internal structure.
-typedef struct vf_VerifyPoolInternal vf_VerifyPoolInternal_t;
-/// Verifier structure of class loader constraint data.
-typedef struct vf_ClassLoaderData vf_ClassLoaderData_t;
+/**
+ * A bytecode instruction.
+ */
+struct vf_Instr
+{
+ unsigned char *m_addr; ///< a start of a bytecode instruction
+ unsigned *m_off; ///< an array of instruction branches
+ vf_MapEntry *m_invector; ///< a stack map IN instruction vector
+ vf_MapEntry *m_outvector; ///< a stack map OUT instruction vector
+ unsigned m_offcount; ///< a number of instruction branches
+ union
+ {
+ vf_NodeHandle m_node; ///< contains a node handle if the corresponding
+ ///< basic block starts at the instruction, NULL otherwise
+ bool m_is_bb_start; ///< if this is a begin of a basic block
+ };
+ unsigned short m_minstack; ///< a minimal stack for instruction
+ unsigned short m_inlen; ///< an IN stack vector length
+ unsigned short m_outlen; ///< an OUT stack vector length
+ short m_stack; ///< a stack change
+ vf_InstrType m_type; ///< an instruction type @see vf_InstrType
+};
+/**
+ * A byte of a bytecode.
+ */
+struct vf_BCode
+{
+ vf_InstrHandle m_instr; ///< a pointer to vf_Context.m_instr
+ bool m_is_bb_start:1; ///< true if the block starts here
+};
+
+/**
+ * Constant pool parse structure.
+ */
+union vf_Parse
+{
+ struct
+ {
+ vf_MapEntry *m_invector; ///< method IN stack vector
+ vf_MapEntry *m_outvector; ///< method OUT stack vector
+ const char *m_name; ///< invoked method name
+ unsigned short m_inlen; ///< IN vector length
+ unsigned short m_outlen; ///< OUT vector length
+ } method;
+ struct
+ {
+ vf_MapEntry *f_vector; ///< field type map vector
+ unsigned short f_vlen; ///< field type map vector len
+ } field;
+};
+
+//===========================================================
+// Pool structures.
+//===========================================================
+
+/**
+ * Internal structure of memory pool.
+ */
+struct vf_PoolInternal
+{
+ void *m_memory; ///< pool entry memory
+ char *m_free; ///< free space in pool entry
+ vf_PoolInternal *m_next; ///< next pool entry
+ size_t m_freesize; ///< size of free space in pool entry
+};
+
+/**
+ * Head structure of memory pool.
+ */
+struct vf_Pool
+{
+ vf_PoolInternal *m_pool; ///< pool entry
+ size_t m_memory; ///< allocated memory size
+ size_t m_used; ///< used memory size
+ size_t m_maxuse; ///< max used memory size
+};
//===========================================================
// Verifier memory management functions diclarations
@@ -277,222 +434,127 @@ typedef struct vf_ClassLoaderData vf_Cla
/**
* Memory pool entry size.
*/
-#define VERIFY_POOL_ENTRY_SIZE 0x2000
+#define VF_POOL_ENTRY_SIZE 0x2000
/**
* Macros hide source line and source file name function arguments.
*/
-#define vf_error() \
- vf_error_func(VERIFY_SOURCE_ARGS0)
-#define vf_calloc(number, size_element) \
- vf_calloc_func((number), (size_element), VERIFY_SOURCE_ARGS0)
-#define vf_malloc(size) \
- vf_malloc_func((size), VERIFY_SOURCE_ARGS0)
-#define vf_free(pointer) \
- vf_free_func((pointer), VERIFY_SOURCE_ARGS0)
-#define vf_realloc(pointer, resize) \
- vf_realloc_func((pointer), (resize), VERIFY_SOURCE_ARGS0)
-#define vf_create_pool() \
- vf_create_pool_func(VERIFY_SOURCE_ARGS0)
-#define vf_alloc_pool_memory(pool, size) \
- vf_alloc_pool_memory_func((pool), (size), VERIFY_SOURCE_ARGS0)
-#define vf_clean_pool_memory(pool) \
- vf_clean_pool_memory_func((pool), VERIFY_SOURCE_ARGS0)
-#define vf_delete_pool(pool) \
- vf_delete_pool_func((pool), VERIFY_SOURCE_ARGS0)
-
-/**
- * Function performs abend exit from VM.
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
- * @see VERIFY_SOURCE_PARAMS
- * @see vf_error
- */
-void vf_error_func( VERIFY_SOURCE_PARAMS );
+#define vf_calloc(number, size_element) \
+ vf_calloc_func((number), (size_element), VF_SOURCE_ARGS0)
+#define vf_malloc(size) \
+ vf_malloc_func((size), VF_SOURCE_ARGS0)
+#define vf_free(pointer) \
+ vf_free_func((pointer), VF_SOURCE_ARGS0)
+#define vf_realloc(pointer, resize) \
+ vf_realloc_func((pointer), (resize), VF_SOURCE_ARGS0)
+#define vf_create_pool() \
+ vf_create_pool_func(VF_SOURCE_ARGS0)
+#define vf_palloc(pool, size) \
+ vf_palloc_func((pool), (size), VF_SOURCE_ARGS0)
+#define vf_clean_pool(pool) \
+ vf_clean_pool_func((pool), VF_SOURCE_ARGS0)
+#define vf_delete_pool(pool) \
+ vf_delete_pool_func((pool), VF_SOURCE_ARGS0)
/**
* Function allocates an array in memory with elements initialized to zero.
* @param number - number of elements
* @param element_size - size of element
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
* @return Pointer to allocated memory block.
- * @see VERIFY_SOURCE_PARAMS
+ * @see VF_SOURCE_PARAMS
* @see vf_calloc
* @note Assertion is raised if number or element_size
* are equal to zero or if out of memory error is arisen.
* @note Trace is available with argument verifier:memory.
*/
void *vf_calloc_func( unsigned number, size_t element_size,
- VERIFY_SOURCE_PARAMS );
+ VF_SOURCE_PARAMS );
/**
* Function allocates memory blocks.
* @param size - size of memory block
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
* @return Pointer to allocated memory block.
- * @see VERIFY_SOURCE_PARAMS
+ * @see VF_SOURCE_PARAMS
* @see vf_malloc
* @note Assertion is raised if size is equal to zero
* or if out of memory error is arisen.
* @note Trace is available with argument verifier:memory.
*/
-void *vf_malloc_func( size_t size, VERIFY_SOURCE_PARAMS );
+void *vf_malloc_func( size_t size, VF_SOURCE_PARAMS );
/**
* Function releases allocated memory blocks.
* @param pointer - pointer to allocated block
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
- * @see VERIFY_SOURCE_PARAMS
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
+ * @see VF_SOURCE_PARAMS
* @see vf_free
* @note Assertion is raised if pointer is equal to null.
* @note Trace is available with argument verifier:memory.
*/
-void vf_free_func( void *pointer, VERIFY_SOURCE_PARAMS );
+void vf_free_func( void *pointer, VF_SOURCE_PARAMS );
/**
* Function reallocates memory blocks.
* @param pointer - pointer to allocated block
* @param resize - new size of memory block
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
* @return Pointer to reallocated memory block.
- * @see VERIFY_SOURCE_PARAMS
+ * @see VF_SOURCE_PARAMS
* @see vf_realloc
* @note Assertion is raised if resize is equal to zero
* or if out of memory error is arisen.
* @note If pointer is equal to null function works like vf_malloc_func.
* @note Trace is available with argument verifier:memory.
*/
-void *vf_realloc_func( void *pointer, size_t resize, VERIFY_SOURCE_PARAMS );
+void *vf_realloc_func( void *pointer, size_t resize, VF_SOURCE_PARAMS );
/**
* Function creates memory pool structure.
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
* @return Pointer to created memory pool.
- * @see VERIFY_SOURCE_PARAMS
+ * @see VF_SOURCE_PARAMS
* @see vf_create_pool
- * @see vf_VerifyPool_t
+ * @see vf_Pool
* @note Trace is available with argument verifier:memory:pool.
*/
-vf_VerifyPool_t *vf_create_pool_func( VERIFY_SOURCE_PARAMS );
+vf_Pool *vf_create_pool_func( VF_SOURCE_PARAMS );
/**
* Function allocates memory blocks in current pool.
* @param pool - pointer to memory pool structure
* @param size - memory block size
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
* @return Pointer to allocated memory block.
- * @see VERIFY_SOURCE_PARAMS
- * @see vf_alloc_pool_memory
- * @see vf_VerifyPool_t
+ * @see VF_SOURCE_PARAMS
+ * @see vf_palloc
+ * @see vf_Pool
* @note Trace is available with argument verifier:memory:pool.
*/
-void *vf_alloc_pool_memory_func( vf_VerifyPool_t * pool, size_t size,
- VERIFY_SOURCE_PARAMS );
+void *vf_palloc_func( vf_Pool *pool, size_t size, VF_SOURCE_PARAMS );
/**
* Function cleans given pool.
* @param pool - memory pool structure
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
- * @see VERIFY_SOURCE_PARAMS
- * @see vf_clean_pool_memory
- * @see vf_VerifyPool_t
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
+ * @see VF_SOURCE_PARAMS
+ * @see vf_clean_pool
+ * @see vf_Pool
* @note Trace is available with argument verifier:memory:pool.
*/
-void
-vf_clean_pool_memory_func( vf_VerifyPool_t * pool, VERIFY_SOURCE_PARAMS );
+void vf_clean_pool_func( vf_Pool *pool, VF_SOURCE_PARAMS );
/**
* Function releases memory from given pool.
* @param pool - memory pool structure
- * @note VERIFY_SOURCE_PARAMS - debug parameters source line and source file name
- * @see VERIFY_SOURCE_PARAMS
+ * @note VF_SOURCE_PARAMS - debug parameters source line and source file name
+ * @see VF_SOURCE_PARAMS
* @see vf_delete_pool
- * @see vf_VerifyPool_t
+ * @see vf_Pool
* @note Trace is available with argument verifier:memory:pool.
*/
-void vf_delete_pool_func( vf_VerifyPool_t * pool, VERIFY_SOURCE_PARAMS );
-
-//===========================================================
-// Code instruction structures.
-//===========================================================
-
-/**
- * A byte of a bytecode.
- */
-struct vf_BCode
-{
- unsigned m_instr; ///< a number + 1 of code instruction at
- ///< vf_Context.m_code
- unsigned m_mark:1; ///< control flow branch flag
-};
-
-/**
- * Valid types structure.
- */
-struct vf_ValidType
-{
- unsigned number; ///< number of types
- const char *string[1]; ///< type array
-};
-
-/**
- * Stack map entry structure.
- */
-struct vf_MapEntry
-{
- vf_ValidType_t *m_vtype; ///< valid type for reference
- union
- {
- unsigned m_new; ///< program count of opcode new for uninitialized
- unsigned m_pc; ///< program count of return address for subroutine
- };
- union
- {
- unsigned short m_local; ///< number of local variable
- unsigned short m_index; ///< constant pool index for access check
- };
- unsigned short m_type:5; ///< stack map type @see vf_MapType_t
- unsigned short m_ctype:4; ///< constraint type @see vf_CheckConstraint_t
- unsigned short m_is_local:1; ///< local variable modify flag
- ///< true - modify local, false - modify stack
-};
-
-/**
- * Complete struct of bytecode instructions.
- */
-struct vf_Code
-{
- unsigned char *m_addr; ///< address of bytecode instruction
- unsigned *m_off; ///< array of instruction branches
- vf_MapEntry_t *m_invector; ///< stack map IN instruction vector
- vf_MapEntry_t *m_outvector; ///< stack map OUT instruction vector
- unsigned m_offcount; ///< number of instruction branches
- unsigned short m_minstack; ///< minimal stack for instruction
- unsigned short m_inlen; ///< stack map IN instruction vector length
- unsigned short m_outlen; ///< stack map OUT instruction vector length
- short m_stack; ///< stack change for instruction
- vf_CodeType m_type; ///< instruction flag @see vf_CodeType_t
- bool m_basic_block_start:1; ///< begin of a basic block
-};
-
-/**
- * Constant pool parse structure.
- */
-union vf_Parse
-{
- struct
- {
- vf_MapEntry_t *m_invector; ///< method IN stack vector
- vf_MapEntry_t *m_outvector; ///< method OUT stack vector
- const char *m_name; ///< invoked method name
- int m_inlen; ///< IN vector length
- int m_outlen; ///< OUT vector length
- } method;
- struct
- {
- vf_MapEntry_t *f_vector; ///< field type map vector
- int f_vlen; ///< field type map vector len
- } field;
-};
+void vf_delete_pool_func( vf_Pool *pool, VF_SOURCE_PARAMS );
//===========================================================
// Verifier hash table structures.
@@ -505,7 +567,7 @@ struct vf_HashEntry
{
const char *key; ///< hash entry key
void *data; ///< pointer to hash entry data
- vf_HashEntry_t *next; ///< next hash entry
+ vf_HashEntry *next; ///< next hash entry
};
/**
@@ -513,7 +575,7 @@ struct vf_HashEntry
*/
struct vf_Hash
{
- public:
+public:
/**
* Hash table constructor.
* @note Function allocates memory for hash pool and hash table.
@@ -525,7 +587,7 @@ struct vf_Hash
* @param pool - external memory pool
* @note Function allocates memory for hash pool and hash table.
*/
- vf_Hash ( vf_VerifyPool_t * pool );
+ vf_Hash ( vf_Pool *pool );
/**
* Hash table destructor.
@@ -537,64 +599,64 @@ struct vf_Hash
* Function looks up hash entry which is identical to given hash key.
* @param key - given hash key
* @return Hash entry which is identical to given hash key.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
*/
- vf_HashEntry_t *Lookup( const char *key );
+ vf_HashEntry *Lookup( const char *key );
/**
* Function looks up hash entry which is identical to given hash key.
* @param key - given hash key
* @param len - hash key length
* @return Hash entry which is identical to given hash key.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
*/
- vf_HashEntry_t *Lookup( const char *key, unsigned len );
+ vf_HashEntry *Lookup( const char *key, size_t len );
/**
* Function creates hash entry which is identical to given hash key.
* @param key - given hash key
* @return Hash entry which are identical to given hash key.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
* @note Created hash key and hash entry is allocated into hash memory pool.
*/
- vf_HashEntry_t *NewHashEntry( const char *key );
+ vf_HashEntry *NewHashEntry( const char *key );
/**
* Function creates hash entry which is identical to given hash key.
* @param key - given hash key
* @param len - hash key length
* @return Hash entry which are identical to given hash key.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
* @note Created hash key and hash entry is allocated into hash memory pool.
*/
- vf_HashEntry_t *NewHashEntry( const char *key, size_t len );
+ vf_HashEntry *NewHashEntry( const char *key, size_t len );
private:
- vf_VerifyPool_t * m_pool; ///< hash memory pool
- vf_HashEntry_t **m_hash; ///< hash table
+ vf_Pool *m_pool; ///< hash memory pool
+ vf_HashEntry **m_hash; ///< hash table
const unsigned HASH_SIZE; ///< hash table size
bool m_free; ///< need to free pool
/**
- * Function checks key identity.
+ * Checks key identity.
* @param hash_entry - checked hash entry
* @param key - checked key
* @return If keys are identical function returns true,
* else returns false.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
*/
- bool CheckKey( vf_HashEntry_t * hash_entry, const char *key );
+ bool CheckKey( vf_HashEntry *hash_entry, const char *key );
/**
- * Function checks key identity.
+ * Checks key identity.
* @param hash_entry - checked hash entry
* @param key - checked key
* @param len - checked key length
* @return If keys are identical function returns true,
* else returns false.
- * @see vf_HashEntry_t
+ * @see vf_HashEntry
*/
- bool CheckKey( vf_HashEntry_t * hash_entry, const char *key, size_t len );
+ bool CheckKey( vf_HashEntry *hash_entry, const char *key, size_t len );
/**
* Hash function.
@@ -617,16 +679,16 @@ struct vf_Hash
//===========================================================
/**
- * Verifier type constraint structure.
+ * A list of constraints.
*/
struct vf_TypeConstraint
{
- const char *source; ///< constraint source class name
- const char *target; ///< constraint target class name
- method_handler method; ///< constraint for method
- vf_TypeConstraint_t *next; ///< next constraint
- unsigned short index; ///< constant pool index
- unsigned short check_type; ///< constraint check type @see vf_CheckConstraint_t
+ const char *m_source; ///< constraint source class name
+ const char *m_target; ///< constraint target class name
+ method_handler m_method; ///< constraint for method
+ vf_TypeConstraint *m_next; ///< next constraint
+ unsigned short m_index; ///< constant pool index
+ unsigned short m_check_type; ///< constraint check type @see vf_CheckConstraint
};
/**
@@ -634,7 +696,7 @@ struct vf_TypeConstraint
*/
struct vf_TypePool
{
- public:
+public:
/**
* Type constraint collection constructor.
* @note Function allocates memory for collection memory pool and hash table.
@@ -652,20 +714,20 @@ struct vf_TypePool
* @param type - given class name
* @param len - class name length
* @return Created valid type structure.
- * @see vf_ValidType_t
+ * @see vf_ValidType
*/
- vf_ValidType_t *NewType( const char *type, size_t len );
+ vf_ValidType *NewType( const char *type, size_t len );
/**
* Function creates valid type which is identical to an element of a given array type.
* @param array - array valid type
* @return Created valid type of a given array element.
- * @see vf_ValidType_t
+ * @see vf_ValidType
*/
- vf_ValidType_t *NewArrayElemType( vf_ValidType_t * array );
+ vf_ValidType *NewArrayElemType( vf_ValidType *array );
/**
- * Function checks types and create constraints if it's necessarily.
+ * Checks types and create constraints if it's necessarily.
* @param required - required type
* @param available - available type
* @param index - constant pool index
@@ -673,12 +735,12 @@ struct vf_TypePool
* @return If available type satisfy to required type
* function will return false (is it error?),
* else will return true (is it error?).
- * @see vf_ValidType_t
- * @see vf_CheckConstraint_t
+ * @see vf_ValidType
+ * @see vf_CheckConstraint
*/
- bool CheckTypes( vf_ValidType_t * required,
- vf_ValidType_t * available,
- unsigned short index, vf_CheckConstraint_t check_type );
+ bool CheckTypes( vf_ValidType *required,
+ vf_ValidType *available,
+ unsigned short index, vf_CheckConstraint check_type );
/**
* Function merges two valid types.
@@ -686,13 +748,12 @@ struct vf_TypePool
* @param second - second merged type
* @return Function returns created valid type corresponding with merge result.
* @return Function returns NULL if vector wasn't merged.
- * @see vf_ValidType_t
+ * @see vf_ValidType
*/
- vf_ValidType_t *MergeTypes( vf_ValidType_t * first,
- vf_ValidType_t * second );
+ vf_ValidType *MergeTypes( vf_ValidType *first, vf_ValidType *second );
/**
- * Function dumps constraint collection in stream.
+ * Dumps constraint collection in stream.
* @param out - pointer to output stream
* @note If out is equal to null, output stream is cerr.
*/
@@ -701,132 +762,155 @@ struct vf_TypePool
/**
* Function returns the methods constraints array.
* @return Array of the methods constraints.
- * @see vf_TypeConstraint_t
+ * @see vf_TypeConstraint
*/
- vf_TypeConstraint_t *GetClassConstraint();
+ vf_TypeConstraint *GetClassConstraint();
/**
- * Function sets current context method.
+ * Sets current context method.
* @param method - current context method
*/
void SetMethod( method_handler method );
/**
- * Function sets restriction from target class to source class.
+ * Sets restriction from target class to source class.
* @param target - target class name
* @param source - source class name
* @param index - constant pool index
* @param check_type - constraint check type
- * @see vf_CheckConstraint_t
+ * @see vf_CheckConstraint
*/
void SetRestriction( const char *target,
const char *source,
unsigned short index,
- vf_CheckConstraint_t check_type );
+ vf_CheckConstraint check_type );
private:
- vf_VerifyPool_t * m_pool; ///< collection memory pool
- vf_Hash_t *m_Hash; ///< hash table
+ vf_Pool *m_pool; ///< collection memory pool
+ vf_Hash *m_Hash; ///< hash table
method_handler m_method; ///< current context method
- vf_TypeConstraint_t *m_restriction; ///< array of the class constraints
+ vf_TypeConstraint *m_restriction; ///< array of the class constraints
}; // vf_TypePool
//===========================================================
// Verifier type constraint structures.
//===========================================================
-void vf_clean_pool_memory_func( vf_VerifyPool_t * pool,
- VERIFY_SOURCE_PARAMS );
+void vf_clean_pool_func( vf_Pool *pool, VF_SOURCE_PARAMS );
/**
- * Structure of verifier context
+ * Verification context.
*/
struct vf_Context
{
- public:
+public:
/**
* Verifier context constructor
*/
vf_Context ():m_class( NULL ), m_type( NULL ), m_error( NULL ),
- m_method( NULL ), m_graph( NULL ), m_pool( NULL ), m_code( NULL ),
- m_codeNum( 0 ), m_nodeNum( 0 ), m_edgeNum( 0 )
+ m_method( NULL ), m_graph( NULL ), m_pool( NULL ), m_instr( NULL ),
+ m_last_instr( NULL ), m_retnum( 0 ), m_verify_all( false )
{
- vf_ContextDump zero1 = { 0 };
vf_ContextVType zero2 = { 0 };
-
- m_dump = zero1;
m_vtype = zero2;
}
+ void SetMethod( method_handler method )
+ {
+ m_method = method;
+
+ // get method parameters
+ m_len = method_get_code_length( method );
+ m_bytes = method_get_bytecode( method );
+ m_handlers = method_get_exc_handler_number( method );
+
+ // get method limitations
+ m_maxlocal = method_get_max_local( method );
+ m_maxstack = method_get_max_stack( method );
+
+ // cache in the context if the method is a constructor
+ m_is_constructor =
+ memcmp( method_get_name( method ), "m_instr
+ vf_BCode *m_bc; ///< bytecode to instruction mapping
+ unsigned m_retnum; ///< a number of rets
+
+ /**
+ * Cached method info.
+ */
+ class_handler m_class; ///< a context class
+ method_handler m_method; ///< a context method
+ unsigned m_len; ///< bytecode length
+ unsigned char *m_bytes; ///< bytecode location
+ unsigned short m_handlers; ///< a number of exception handlers
+ unsigned short m_maxstack; ///< max stack length
+ unsigned short m_maxlocal; ///< max local number
bool m_is_constructor; ///< true if the
///< method is a constructor
+ vf_SubContext *m_sub_ctx; ///< aggregate subroutine info
+ vf_MapVector *m_map; ///< a stack map for control flow analysis,
+ ///< vectors themselves are allocated from the graph pool
+ vf_MapEntry *m_method_invector; ///< method parameters
+ unsigned short m_method_inlen; ///< a length of m_method_invector
+ vf_MapEntry *m_method_outvector; ///< method return value
+ unsigned short m_method_outlen; ///< a length of m_method_outvector
+
+ vf_MapEntry *m_buf; ///< used to store intermediate stack states
+ ///< during data flow analysis
+
+ bool m_verify_all; ///< if true need to verify more checks
+
/**
- * Structure contains useful valid types
+ * Contains useful valid types.
*/
struct vf_ContextVType
{
- vf_ValidType_t *m_class; ///< context a given class valid type
- vf_ValidType_t *m_throwable; ///< context java/lang/Throwable valid type
- vf_ValidType_t *m_object; ///< context java/lang/Object valid type
- vf_ValidType_t *m_array; ///< context [Ljava/lang/Object; valid type
- vf_ValidType_t *m_clone; ///< context java/lang/Cloneable valid type
- vf_ValidType_t *m_serialize; ///< context java/io/Serializable valid type
+ vf_ValidType *m_class; ///< a given class
+ vf_ValidType *m_throwable; ///< java/lang/Throwable
+ vf_ValidType *m_object; ///< java/lang/Object
+ vf_ValidType *m_array; ///< [Ljava/lang/Object;
+ vf_ValidType *m_clone; ///< java/lang/Cloneable
+ vf_ValidType *m_serialize; ///< java/io/Serializable
} m_vtype;
- /**
- * Structure contains debug dump flags
- */
- struct vf_ContextDump
- {
- unsigned m_verify:1; ///< verify all flag
- unsigned m_with_subroutine:1; ///< verified method has subroutine
- unsigned m_constraint:1; ///< dump type constraints for class
- unsigned m_code:1; ///< print code array in stream
- unsigned m_graph:1; ///< print original control flow graph
- unsigned m_mod_graph:1; ///< print modified control flow graph
- unsigned m_dot_graph:1; ///< dump original control flow graph in file in DOT format
- unsigned m_dot_mod_graph:1; ///< dump modified control flow graph in file in DOT format
- unsigned m_node_vector:1; ///< print data flow node vectors
- unsigned m_code_vector:1; ///< print data flow node code instruction vectors
- unsigned m_merge_vector:1; ///< print result of merge data flow vectors
- } m_dump;
-
}; // struct vf_Context
//===========================================================
@@ -834,36 +918,15 @@ struct vf_Context
//===========================================================
/**
- * Head structure of memory pool.
- */
-struct vf_VerifyPool
-{
- vf_VerifyPoolInternal_t *m_pool; ///< pool entry
- size_t m_memory; ///< allocated memory size
- size_t m_used; ///< used memory size
- size_t m_maxuse; ///< max used memory size
-};
-
-/**
- * Internal structure of memory pool.
- */
-struct vf_VerifyPoolInternal
-{
- void *m_memory; ///< pool entry memory
- char *m_free; ///< free space in pool entry
- vf_VerifyPoolInternal_t *m_next; ///< next pool entry
- size_t m_freesize; ///< size of free space in pool entry
-};
-
-/**
* Structure of class loader constraint data.
*/
struct vf_ClassLoaderData
{
- vf_VerifyPool_t *pool; ///< constraint memory pool
- vf_Hash_t *string; ///< string pool hash table
+ vf_Pool *pool; ///< constraint memory pool
+ vf_Hash *string; ///< string pool hash table
};
+
//===========================================================
// Verifier debug data
//===========================================================
@@ -871,9 +934,9 @@ struct vf_ClassLoaderData
/**
* Array of opcode names. Available in debug mode.
*/
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
extern const char *vf_opcode_names[];
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
//===========================================================
// Verifier functions.
@@ -881,12 +944,12 @@ extern const char *vf_opcode_names[];
/**
* Function creates bytecode control flow graph.
- * @param context - verifier context
+ * @param ctx - verifier context
* @return Result of graph creation.
- * @see vf_Context_t
- * @see Verifier_Result
+ * @see vf_Context
+ * @see vf_Result
*/
-Verifier_Result vf_create_graph( vf_Context_t * context );
+vf_Result vf_create_graph( vf_Context *ctx );
/**
* Checks control flow and data flow of graph.
@@ -895,52 +958,50 @@ Verifier_Result vf_create_graph( vf_Cont
*
* @return a result of graph checks
*/
-Verifier_Result vf_check_graph( vf_Context_t * context );
+vf_Result vf_check_graph( vf_Context *ctx );
/**
- * Function provides data flow checks of verifier graph structure.
- * @param context - verifier context
+ * Provides data flow checks of verifier graph structure.
+ * @param ctx - verifier context
* @return Check result.
- * @see vf_Context_t
- * @see Verifier_Result
+ * @see vf_Context
+ * @see vf_Result
*/
-Verifier_Result vf_check_graph_data_flow( vf_Context_t * context );
+vf_Result vf_check_graph_data_flow( vf_Context *ctx );
/**
- * Function parses method, class or field descriptors.
- * @param descr - descriptor of method, class or field
- * @param inlen - returned number of IN descriptor parameters
- * @param outlen - returned number of OUT descriptor parameters (for method)
- * @note Assertion is raised if descr or inlen are equal to null.
+ * Parses method, class or field descriptors.
+ * @param descr descriptor of method, class or field
+ * @param inlen returned number of IN descriptor parameters
+ * @param outlen returned number of OUT descriptor parameters (for method)
+ * @note Assertion is raised if descr or inlen are equal to NULL.
* @note Parameter outlen may be equal to null (for class or field descriptor).
*/
-void vf_parse_description( const char *descr, int *inlen, int *outlen );
+void vf_parse_description( const char *descr, unsigned short *inlen,
+ unsigned short *outlen );
/**
- * Function parses descriptor and sets input and output data flow vectors.
- * @param descr - descriptor of method, class or field
- * @param inlen - number of entries for IN data flow vector
- * @param add - additional number of entries to IN data flow vector
- * @param outlen - number of entries for OUT data flow vector (for method)
- * @param invector - pointer to IN data flow vector
- * @param outvector - pointer to OUT data flow vector
- * @param context - verifier context
+ * Parses a descriptor and sets input and output data flow vectors.
+ * @param descr a descriptor of method, class or field
+ * @param inlen a number of entries for IN data flow vector
+ * @param add an additional number of entries to IN data flow vector
+ * @param outlen a number of entries for OUT data flow vector (for method)
+ * @param invector a pointer to IN data flow vector
+ * @param outvector a pointer to OUT data flow vector
+ * @param ctx a verifier context
* @note Assertion is raised if descr is equal to null.
* @note Parameter invector may be equal to null
* if sum of parameters inlen + add is equal to zero.
* @note Parameter outvector may be equal to null
* if parameter outlen is equal to zero.
- * @see vf_MapEntry_t
- * @see vf_Context_t
*/
void
vf_set_description_vector( const char *descr,
- int inlen,
- int add,
- int outlen,
- vf_MapEntry_t ** invector,
- vf_MapEntry_t ** outvector,
- vf_Context_t * context );
+ unsigned short inlen,
+ unsigned short add,
+ unsigned short outlen,
+ vf_MapEntry **invector,
+ vf_MapEntry **outvector, vf_ContextHandle ctx );
/**
* Gets a class name from a constant pool.
@@ -960,38 +1021,36 @@ vf_get_cp_class_name( class_handler klas
} // vf_get_cp_class_name
/**
- * Function creates valid type by given class name.
- * @param class_name - class name
- * @param context - verifier context
- * @return Valid type structure corresponding to given class name.
- * @see vf_ValidType_t
- * @see vf_Context_t
+ * Creates a valid type from a given class name.
+ * @param class_name a class name
+ * @param ctx a verifier context
+ * @return a valid type structure corresponding to the given class name
*/
-vf_ValidType_t *vf_create_class_valid_type( const char *class_name,
- vf_Context_t * context );
+vf_ValidType *vf_create_class_valid_type( const char *class_name,
+ vf_ContextHandle ctx );
/**
- * Function provides constraint checks for current class.
- * @param context - verifier context
+ * Provides constraint checks for current class.
+ * @param ctx - verifier context
* @return Check result.
* @note Provides only checks with loaded classes.
* @note All unchecked constraints are saved to class loader verify data.
- * @see vf_Context_t
- * @see Verifier_Result
+ * @see vf_Context
+ * @see vf_Result
*/
-Verifier_Result vf_check_class_constraints( vf_Context_t * context );
+vf_Result vf_check_class_constraints( vf_Context *ctx );
/**
* Function compares two valid types.
* @param type1 - first checked type
* @param type2 - second checked type
* @return If types are equal returns true, else returns false.
- * @see vf_ValidType_t
+ * @see vf_ValidType
*/
-bool vf_is_types_equal( vf_ValidType_t * type1, vf_ValidType_t * type2 );
+bool vf_is_types_equal( vf_ValidType *type1, vf_ValidType *type2 );
/**
- * Function checks access to protected field/method.
+ * Checks access to protected field/method.
* If function cannot check constraint because of any class isn't loaded,
* function return unloaded error to store restriction to the class
* for future constraint check.
@@ -999,42 +1058,41 @@ bool vf_is_types_equal( vf_ValidType_t *
* @param instance_name - name of instance class
* @param index - constant pool index
* @param check_type - access check type
- * @param ctex - verifier context
+ * @param ctx - verifier context
* @return Check result.
* @note Provides only checks with loaded classes.
- * @see vf_CheckConstraint_t
- * @see vf_Context_t
- * @see Verifier_Result
- */
-Verifier_Result vf_check_access_constraint( const char *super_name, // name of super class
- const char *instance_name, // name of instance class
- unsigned short index, // constant pool index
- vf_CheckConstraint_t check_type, // access check type
- vf_Context_t * ctex ); // verifier context
+ * @see vf_CheckConstraint
+ * @see vf_Context
+ * @see vf_Result
+ */
+vf_Result vf_check_access_constraint( const char *super_name, // name of super class
+ const char *instance_name, // name of instance class
+ unsigned short index, // constant pool index
+ vf_CheckConstraint check_type, // access check type
+ vf_Context *ctx ); // verification context
/**
- * Sets error message of verifier.
+ * Sets error message of a verifier.
*
* @param[in] stream stringstream object with a message
- * @param[in] ctex a verifier context
+ * @param[in] ctx a verifier context
*/
static inline void
-vf_set_error_message( stringstream & stream, vf_Context_t * ctex )
+vf_set_error_message( stringstream & stream, vf_Context *ctx )
{
- if( ctex->m_error ) {
+ if( ctx->m_error ) {
// free old message
- vf_free( ctex->m_error );
+ vf_free( ctx->m_error );
}
// create message
size_t len = stream.str().length();
if( len ) {
- ctex->m_error = (char*)vf_malloc( len + 1 );
- memcpy( ctex->m_error, stream.str().c_str(), len );
- ctex->m_error[len] = '\0';
+ ctx->m_error = (char*)vf_malloc( len + 1 );
+ memcpy( ctx->m_error, stream.str().c_str(), len );
+ ctx->m_error[len] = '\0';
} else {
- ctex->m_error = NULL;
+ ctx->m_error = NULL;
}
- return;
} // vf_set_error_message
/**
@@ -1045,25 +1103,25 @@ vf_set_error_message( stringstream & str
* @return true if a class version is less than 1.4
*/
static inline bool
-vf_is_class_version_14( vf_Context_t * context )
+vf_is_class_version_14( vf_ContextHandle ctx )
{
- return ( class_get_version( context->m_class ) < 49 ) ? true : false;
+ return ( class_get_version( ctx->m_class ) < 49 ) ? true : false;
} // vf_is_class_version_14
/**
* Returns branch target for a given branch number.
*
- * @param[in] code a reference to instruction
+ * @param[in] instr a reference to instruction
* @param[in] branch_num a branch number
*
* @return an absolute bytecode position to which the executuion
* branches
*/
static inline int
-vf_get_code_branch( vf_Code_t * code, unsigned branch_num )
+vf_get_instr_branch( vf_InstrHandle instr, unsigned branch_num )
{
- assert( branch_num < code->m_offcount );
- return code->m_off[branch_num];
+ assert( branch_num < instr->m_offcount );
+ return instr->m_off[branch_num];
} // vf_get_instruction_branch
/**
@@ -1074,14 +1132,11 @@ vf_get_code_branch( vf_Code_t * code, un
* @param[in] pool memory pool
*/
static inline void
-vf_new_vector( vf_MapEntry_t ** vector, unsigned len, vf_VerifyPool_t * pool )
+vf_new_vector( vf_MapEntry **vector, unsigned len, vf_Pool *pool )
{
// create new vector
- ( *vector ) = (vf_MapEntry_t*) vf_alloc_pool_memory( pool,
- len *
- sizeof
- ( vf_MapEntry_t ) );
- return;
+ ( *vector ) = (vf_MapEntry*)vf_palloc( pool,
+ len * sizeof( vf_MapEntry ) );
} // vf_new_vector
/**
@@ -1092,8 +1147,8 @@ vf_new_vector( vf_MapEntry_t ** vector,
* @param[in] type reference type
*/
static inline void
-vf_set_vector_stack_entry_ref( vf_MapEntry_t * vector,
- unsigned num, vf_ValidType_t * type )
+vf_set_vector_stack_entry_ref( vf_MapEntry *vector,
+ unsigned num, vf_ValidType *type )
{
// set a stack map vector entry by ref
vector[num].m_type = SM_REF;
@@ -1101,14 +1156,44 @@ vf_set_vector_stack_entry_ref( vf_MapEnt
} // vf_set_vector_stack_entry_ref
/**
+ * Calculates an index of instruction.
+ * @param[in] pc a bytecode index at instruction start
+ * @param[in] ctx a verification context
+ * @return an instruction index
+ */
+static inline unsigned
+vf_bc_to_instr_index( unsigned short pc, vf_ContextHandle ctx )
+{
+ vf_InstrHandle instr = ctx->m_bc[pc].m_instr;
+ assert( instr );
+ return instr - ctx->m_instr;
+}
+
+/**
+ * For a given instruction gets a start pointer of the next instruction or the
+ * pointer which follows the last bytecode of the method for the last instruction.
+ * @param[in] instr an instruction handle
+ * @param[in] ctx a verification context
+ * @return a pointer which follows a given instruction
+ */
+static inline const unsigned char *
+vf_get_instr_end( vf_InstrHandle instr, vf_ContextHandle ctx )
+{
+ if( instr + 1 == ctx->m_last_instr ) {
+ return ctx->m_bytes + ctx->m_len;
+ }
+ return ( instr + 1 )->m_addr;
+}
+
+/**
* Calls destructor of graph, if any.
*
* @param[in] context a context of verifier
*/
-void vf_free_graph( vf_Context_t * context );
+void vf_free_graph( vf_Context *context );
/**
- * Inline subroutines in the call graph.
+ * Mark subroutine code.
*
* Here is the algorithm sketch: we define subroutine boundaries with * simplified data flow analysis and duplicate subroutine nodes @@ -1116,10 +1201,19 @@ void vf_free_graph( vf_Context_t * conte * wiki * page.
* - * @param[in] context a verifier context + * @param ctx a verifier context + * @return VER_OK if no graph structure inconsistencies were detected during marking, + * an error code otherwise + */ +vf_Result vf_mark_subroutines( vf_Context *ctx ); + +/** + * Inline subroutines in the call graph. + * + * @param ctx a verifier context * @return VER_OK if subroutines were inlined successfully, * an error code otherwise */ -Verifier_Result vf_inline_subroutines( vf_ContextHandle context ); +vf_Result vf_inline_subroutines( vf_Context *ctx ); #endif // _VERIFIER_REAL_H_ diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.cpp 91/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.cpp --- 9/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.cpp Tue Mar 20 19:34:51 2007 +++ 91/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.cpp Tue Apr 03 19:59:02 2007 @@ -16,24 +16,579 @@ */ #include "ver_subroutine.h" -static vf_Result MarkTopcode(vf_ContextHandle context, vf_NodeHandle nh) +#ifdef _VF_DEBUG +/** + * Gets a subroutine number for a node. The function is slow and should be used for + * debugging purposes only. + * @param[in] sub a given subroutine handle + * @param[in] ctx a verification context + * @return a sequential subroutine number in a list + */ +unsigned vf_get_sub_num(vf_SubHandle sub, vf_ContextHandle ctx) { + unsigned index = 0; + for (vf_SubHandle s = ctx->m_sub_ctx->m_sub; s; s = s->m_next) { + if (s == sub) { // subroutine found + return index; + } + index++; + } + VF_DIE("vf_get_sub_num: Cannot find a subroutine " << sub << + " in a list"); + return 0; +} + +void vf_Graph::DumpSub(vf_SubHandle sub) +{ + if (sub) { + VF_DEBUG("Subroutine:"); + if (sub->m_entry) { + VF_DEBUG(" Entry node: " << GetNodeNum(sub->m_entry)); + } else { + VF_DEBUG(" Entry node undefined"); + } + if (sub->m_ret) { + VF_DEBUG(" Return node: " << GetNodeNum(sub->m_ret)); + } else { + VF_DEBUG(" Return node undefined"); + } + } +} // vf_Graph::DumpSub + +static void DumpNodeStack(vf_Context *ctx) +{ + vf_NodeStackHandle p_element = ctx->m_sub_ctx->m_path_start; + bool fork_found = false; + unsigned count = 0; + + VF_DEBUG("Dumping path: "); + for (; p_element; p_element = p_element->m_next, count++) { + if (p_element == ctx->m_sub_ctx->m_path_fork) { + fork_found = true; + VF_DEBUG("Fork"); + } + VF_DEBUG(" Node #" << ctx->m_graph->GetNodeNum(p_element->m_node)); + } + assert(fork_found || !ctx->m_sub_ctx->m_path_fork); + VF_DEBUG("Totally " << count << " nodes"); +} // DumpNodeStack +#endif // _VF_DEBUG + + +/** + * Allocates memory for subroutine context. + * @param ctx a verification context + */ +static void AllocateSubContext(vf_Context *ctx) +{ + vf_Pool *pool = ctx->m_pool; + + vf_SubContext *sub_ctx = (vf_SubContext *) vf_palloc(pool, + sizeof(vf_SubContext)); + ctx->m_sub_ctx = sub_ctx; + sub_ctx->m_pool = pool; +} // AllocateSubContext + + +/** + * Adds a new subroutine into subroutine array. + * @param[in] ret_node a node containing a correspondingret
+ * @param[in] sub_ctx a subroutine verification context
+ * @return a sub handle
+ */
+static vf_Sub *AddNewSub(vf_NodeHandle ret_node, vf_SubContext * sub_ctx)
+{
+ vf_Sub *sub = (vf_Sub *) vf_palloc(sub_ctx->m_pool, sizeof(vf_Sub));
+ sub->m_next = sub_ctx->m_sub;
+ sub_ctx->m_sub = sub;
+ sub->m_ret = ret_node;
+ return sub;
+} // AddNewSub
+
+/**
+ * Adds a node to the subroutine.
+ * @param[in] sub a subroutine
+ * @param[in] node a node which is a part of this subroutine
+ */
+static void AddSubNode(vf_Sub *sub, vf_Node *node)
+{
+ assert(!node->m_sub); // node is added once
+ node->m_sub = sub;
+ sub->m_nodenum++;
+ // a number of out edges for reachable node won't
+ // change while removing a dead code
+ sub->m_out_edgenum += node->m_outnum;
+} // AddNewSub
+
+static inline vf_Result ResolveSubroutineEntryPoint(vf_Node *node,
+ vf_Context *ctx)
+{
+ //initialize vector
+ vf_MapVector *map = ctx->m_map;
+
+ // the path element node to iterate from
+ vf_NodeStackHandle p_element = ctx->m_sub_ctx->m_path_fork;
+ if (!p_element) {
+ p_element = ctx->m_sub_ctx->m_path_start;
+ map->m_number = ctx->m_maxlocal;
+ unsigned index;
+ for (index = 0; index < map->m_number; index++) {
+ map->m_local[index].m_type = SM_ANY;
+ }
+
+ map->m_depth = p_element->m_node->m_inmap.m_depth;
+ for (index = 0; index + 1 < map->m_depth; index++) {
+ map->m_stack[index].m_type = SM_ANY;
+ }
+ map->m_stack[index].m_type = SM_RETURN_ADDR;
+ map->m_stack[index].m_pc =
+ p_element->m_node->m_start->m_addr - ctx->m_bytes;
+ }
+
+ VF_DUMP(DUMP_NODESTACK, DumpNodeStack(ctx));
+ for (; p_element; p_element = p_element->m_next) {
+ vf_Result result =
+ vf_set_node_out_vector(p_element->m_node, map, ctx);
+ if (result != VER_OK) {
+ return result;
+ }
+ }
+
+ // since a copy flag is set for SM_RETURN_ADDR entries,
+ // ctx->m_buf contains the last processed entry, i. e.
+ // an entry for ret
+ assert(ctx->m_buf->m_pc);
+ assert(SM_RETURN_ADDR == ctx->m_buf->m_type);
+ assert(node->m_outmap.m_depth == ctx->m_map->m_depth);
+ ((vf_Sub *) node->m_sub)->m_entry =
+ ctx->m_graph->GetNodeFromBytecodeIndex(ctx->m_buf->m_pc);
return VER_OK;
-} // MarkTopcode
+} // ResolveSubroutineEntryPoint
+
+static vf_Result MarkNode(vf_NodeStack &stack, vf_Context *ctx);
-static vf_Result InlineMarkedSubNodes(vf_ContextHandle context)
+/**
+ * Fills m_sub field of the node using m_sub field of
+ * the next node using the following rules:
+ * jsr edge end node. If the subroutine returns, marks a node, which
+ * follows the edge start node.
+ */
+static inline vf_Result
+FollowJsrEdge(vf_Node *node, vf_NodeStack &stack, vf_Context *ctx)
+{
+ bool set_start = !ctx->m_sub_ctx->m_path_start;
+ if (set_start) {
+ ctx->m_sub_ctx->m_path_start = &stack;
+ }
+ vf_Result r = MarkNode(stack, ctx);
if (VER_OK != r) {
return r;
}
- r = InlineMarkedSubNodes(context);
+ if (stack.m_node->m_sub) {
+ // if this jsr returns we need to process a node which
+ // follows after edge start node
+ if (stack.m_node->m_sub->m_entry != stack.m_node) {
+ VF_REPORT(ctx, "Subroutines merge their execution");
+ return VER_ErrorDataFlow;
+ }
+
+ ctx->m_sub_ctx->m_path_fork = &stack;
+
+ // select and check the following node
+ stack.Set(node + 1, stack.m_node->m_sub->m_ret->m_outmap.m_depth);
+ if (VF_NODE_END_ENTRY == stack.m_node->m_type) {
+ VF_REPORT(ctx, "Falling off the end of the code");
+ return VER_ErrorBranch;
+ }
+ assert(VF_NODE_CODE_RANGE == stack.m_node->m_type);
+
+ r = MarkNode(stack, ctx);
+ ctx->m_sub_ctx->m_path_fork = NULL;
+ if (VER_OK != r) {
+ return r;
+ }
+ }
+
+ if (set_start) {
+ ctx->m_sub_ctx->m_path_start = NULL;
+ }
+ return MergeSubMarks(node, stack.m_node, ctx);
+} // FollowJsrEdge
+
+/**
+ * Marks a given node and follows out edges.
+ * @param[in] stack a reference to the stack element for the given node
+ * @param[in] ctx a verification context
+ * @return VER_OK if marking was successful, an error code otherwise
+ */
+static vf_Result MarkNode(vf_NodeStack &stack, vf_Context *ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+ vf_Result r;
+
+ vf_Result result =
+ vf_check_node_stack_depth(stack.m_node, stack.m_depth, ctx);
+ if (result != VER_Continue) {
+ return result;
+ }
+ VF_TRACE("sub.mark",
+ "Processing node " << graph->GetNodeNum(stack.m_node));
+
+ if (VF_NODE_CODE_RANGE == stack.m_node->m_type) {
+ vf_InstrType last_instr_type = stack.m_node->m_end->m_type;
+
+ if (VF_INSTR_RET == last_instr_type) {
+ if (!ctx->m_sub_ctx->m_path_start) {
+ VF_REPORT(ctx, "Reached ret not using jsr branches");
+ return VER_ErrorJsrOther;
+ }
+ vf_Sub *sub = AddNewSub(stack.m_node, ctx->m_sub_ctx);
+ AddSubNode(sub, stack.m_node);
+ r = ResolveSubroutineEntryPoint(stack.m_node, ctx);
+ if (VER_OK != r) {
+ return r;
+ }
+ }
+ }
+
+ vf_NodeStack next_stack;
+ stack.m_next = &next_stack;
+ for (vf_EdgeHandle outedge = stack.m_node->m_outedge;
+ outedge; outedge = outedge->m_outnext) {
+ next_stack.Set(outedge->m_end, stack.m_depth);
+ if (!vf_is_jsr_branch(outedge, ctx)) {
+ r = FollowEdge(stack.m_node, next_stack, ctx);
+ } else {
+ assert(VF_NODE_CODE_RANGE == outedge->m_end->m_type);
+ assert(!outedge->m_outnext);
+ r = FollowJsrEdge(stack.m_node, next_stack, ctx);
+ }
+ if (VER_OK != r) {
+ return r;
+ }
+ }
+
+ return VER_OK;
+} // MarkNode
+
+
+vf_Result vf_mark_subroutines(vf_Context *ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+ AllocateSubContext(ctx);
+
+ vf_NodeStack bottom =
+ { (vf_Node *) ctx->m_graph->GetStartNode(), 0, NULL };
+ vf_Result r = MarkNode(bottom, ctx);
return r;
-} // InlineSubroutines
+} // vf_mark_subroutines
+
+static vf_Result AddDupCount(vf_Sub *sub, unsigned &count, vf_Context *ctx)
+{
+ VF_TRACE("dupcount", "Calculating a duplication count for a subroutine #"
+ << vf_get_sub_num(sub, ctx));
+ if (ALL_BITS_SET == sub->m_dupcount) {
+ VF_REPORT(ctx, "Found a recursive subroutine call sequence");
+ return VER_ErrorJsrRecursive;
+ }
+
+ if (!sub->m_dupcount) {
+ sub->m_dupcount = ALL_BITS_SET;
+
+ unsigned sum = 0;
+ for (vf_EdgeHandle inedge = sub->m_entry->m_inedge;
+ inedge; inedge = inedge->m_innext) {
+ vf_NodeHandle node = inedge->m_start;
+
+ if (vf_is_jsr_branch(inedge, ctx)) {
+ assert(!inedge->m_outnext);
+ if (node->m_sub == NULL) {
+ sum++;
+ } else if (node->m_sub != sub) {
+ AddDupCount((vf_Sub *) node->m_sub, sum, ctx);
+ } // else this call served as unconditional internal branch
+ } else if (node->m_sub != sub) {
+ VF_REPORT(ctx,
+ "A subroutine splits execution into "
+ "several ret instructions");
+ return VER_ErrorJsrMultipleRet;
+ }
+ }
+ sub->m_dupcount = sum;
+ }
+
+ VF_TRACE("dupcount", "A duplication count for a subroutine #"
+ << vf_get_sub_num(sub, ctx) << " is " << sub->m_dupcount);
+ count += sub->m_dupcount;
+ return VER_OK;
+} // AddSubDupCount
+
+static void InlineSubNodes(vf_ContextHandle ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+ vf_Sub *sub;
+
+ for (sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ sub->m_nodes =
+ (vf_NodeHandle *) vf_palloc(ctx->m_sub_ctx->m_pool,
+ sub->m_nodenum * sizeof(vf_NodeHandle));
+ }
+
+ // populate subroutine node get the next node after the start node
+ vf_Node *node = (vf_Node *) graph->GetStartNode() + 1;
+ for (; VF_NODE_END_ENTRY != node->m_type; node++) {
+ if (node->m_sub) {
+ vf_Sub *sub = (vf_Sub *) node->m_sub;
+ node->m_nodecount = sub->m_index;
+ sub->m_nodes[sub->m_index++] = node;
+ }
+ }
+
+ // clear sub indices
+ for (sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ assert(sub->m_nodenum == sub->m_index);
+ sub->m_index = 0;
+ }
+
+ // duplicate subroutine nodes
+ for (sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ vf_NodeHandle *p_node = sub->m_nodes;
+ vf_NodeHandle new_node;
+ for (unsigned node_index = 0; node_index < sub->m_nodenum;
+ node_index++, p_node++) {
+
+ for (unsigned index = 1; index < sub->m_dupcount; index++) {
+ new_node = ctx->m_graph->NewNode(*p_node);
+ VF_TRACE("sub.inline",
+ "Copied node " << graph->GetNodeNum(*p_node)
+ << " to " << graph->GetNodeNum(new_node));
+ }
+
+ }
+ if (sub->m_dupcount > 1) {
+ sub->m_copies =
+ (vf_Node *) new_node - (sub->m_dupcount -
+ 1) * sub->m_nodenum + 1;
+ }
+ }
+ assert(0 == ctx->m_graph->HasMoreNodeSpace());
+
+} // InlineSubNodes
+
+/**
+ * Redirects subroutine calls to separate subroutine copies.
+ */
+static void InlineInEdges(vf_ContextHandle ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+
+ for (vf_SubHandle sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ ((vf_Sub *) sub)->m_following_nodes =
+ (vf_Node **) vf_palloc(ctx->m_sub_ctx->m_pool,
+ sub->m_dupcount * sizeof(vf_Node *));
+ vf_NodeHandle sub_entry_copy =
+ sub->m_copies + sub->m_entry->m_nodecount * (sub->m_dupcount -
+ 1) - 1;
+ vf_EdgeHandle *p_next_edge =
+ (vf_EdgeHandle *) & sub->m_entry->m_inedge;
+ vf_Edge *inedge = (vf_Edge *) sub->m_entry->m_inedge;
+ while (inedge) {
+ if (vf_is_jsr_branch(inedge, ctx)) {
+ if (sub->m_index) {
+ assert(sub->m_copies);
+ assert(sub->m_dupcount);
+ // remove the edge from the list
+ *p_next_edge = inedge->m_innext;
+ // redirect jsr edge to correspondent subroutine copy
+ inedge->m_end = sub_entry_copy + sub->m_index;
+ }
+ // store return point
+ vf_Node *next_node = (vf_Node *) inedge->m_start + 1;
+ assert(VF_NODE_CODE_RANGE == next_node->m_type);
+ sub->m_following_nodes[((vf_Sub *) sub)->m_index++] =
+ next_node;
+ }
+ p_next_edge = &inedge->m_innext;
+ inedge = (vf_Edge *) inedge->m_innext;
+ }
+ assert(sub->m_index); // there was at least one branch
+ }
+} // InlineInEdges
+
+/**
+ * Subroutine calls are redirected to correspondent subroutine copies,
+ * other edges are just duplicated.
+ */
+static void InlineOutEdges(vf_ContextHandle ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+
+ for (vf_SubHandle sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ if (!sub->m_copies) {
+ continue;
+ }
+ vf_Node *copy = sub->m_copies;
+ for (unsigned node_index = 0; node_index < sub->m_nodenum;
+ node_index++, copy += sub->m_dupcount - 1) {
+ vf_NodeHandle node = sub->m_nodes[node_index];
+
+ for (vf_EdgeHandle outedge = node->m_outedge; outedge;
+ outedge = outedge->m_outnext) {
+ vf_NodeHandle end_node = outedge->m_end;
+ vf_SubHandle end_sub = end_node->m_sub;
+
+ vf_Node *c = copy;
+ if (NULL == end_sub) {
+ for (unsigned index = 1; index < sub->m_dupcount; index++) {
+ graph->NewEdge(c++, (vf_Node *) end_node);
+ }
+ } else if (node->m_sub == end_sub) {
+ vf_Node *e = sub->m_copies +
+ end_node->m_nodecount * (sub->m_dupcount - 1);
+ for (unsigned index = 1; index < sub->m_dupcount; index++) {
+ graph->NewEdge(c++, e++);
+ }
+ } else {
+ assert(vf_is_jsr_branch(outedge, ctx));
+ assert(!outedge->m_outnext);
+ // an end node
+ vf_Node *e = end_sub->m_copies +
+ end_sub->m_entry->m_nodecount *
+ (end_sub->m_dupcount - 1) - 1;
+ // a node next to the start node
+ vf_Node *n = c + (sub->m_dupcount - 1);
+ for (unsigned index = 1;
+ index < node->m_sub->m_dupcount; index++) {
+ // direct jsr edge to correspondent subroutine copy
+ graph->NewEdge(c++, e + end_sub->m_index);
+ // store return point
+ assert(VF_NODE_CODE_RANGE == n->m_type);
+ end_sub->m_following_nodes[((vf_Sub *) end_sub)->
+ m_index++] = n++;
+ }
+ }
+ }
+ }
+ }
+} // InlineOutEdges
+
+/**
+ * Adds a back branch from ret nodes to a node
+ * which follows the correspondent jsr call node.
+ */
+static void InlineRetEdges(vf_ContextHandle ctx)
+{
+ vf_Graph *graph = ctx->m_graph;
+ for (vf_SubHandle sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+
+ vf_Node *ret_node = (vf_Node *) sub->m_ret;
+ vf_Node **next_node = sub->m_following_nodes;
+ graph->NewEdge(ret_node, *(next_node++));
+
+ vf_Node *ret_node_copy =
+ sub->m_copies + ret_node->m_nodecount * (sub->m_dupcount - 1);
+ for (unsigned index = 1; index < sub->m_dupcount; index++) {
+ // direct ret entry to the return point
+ graph->NewEdge(ret_node_copy++, *(next_node++));
+ }
+ }
+ assert(0 == ctx->m_graph->HasMoreEdgeSpace());
+} // InlineRetEdges
+
+/**
+ * Checks that every subroutine copy gets its call and
+ * all edges are created.
+ */
+static void CheckDupCounts(vf_ContextHandle ctx)
+{
+#if _VF_DEBUG
+ for (vf_SubHandle sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ assert(sub->m_dupcount == sub->m_index);
+ }
+#endif // _VF_DEBUG
+}
+
+/**
+ * Calculates a number of additional nodes and edges and adds them
+ * to the graph.
+ */
+vf_Result vf_inline_subroutines(vf_Context *ctx)
+{
+ if (NULL == ctx->m_sub_ctx->m_sub) {
+ // subroutines are not reachable
+ return VER_OK;
+ }
+
+ unsigned count;
+ unsigned nodes = 0, edges = 0;
+ for (vf_Sub *sub = ctx->m_sub_ctx->m_sub; sub; sub = sub->m_next) {
+ vf_Result r = AddDupCount(sub, count, ctx);
+ if (VER_OK != r) {
+ return r;
+ }
+ // one copy already present in the graph
+ nodes += (sub->m_dupcount - 1) * sub->m_nodenum;
+ edges += (sub->m_dupcount - 1) * sub->m_out_edgenum;
+ // there is an additional edge from every ret
+ edges += sub->m_dupcount;
+ }
+ ctx->m_graph->CreateEdges(edges);
+
+ if (nodes) {
+ ctx->m_graph->CreateNodes(nodes);
+ InlineSubNodes(ctx);
+ }
+ InlineInEdges(ctx);
+
+ if (nodes) {
+ InlineOutEdges(ctx);
+ }
+
+ CheckDupCounts(ctx);
+ InlineRetEdges(ctx);
+ return VER_OK;
+} // vf_inline_subroutines
diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.h 91/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.h
--- 9/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.h Tue Mar 20 19:34:50 2007
+++ 91/trunk/working_vm/vm/vmcore/src/verifier\ver_subroutine.h Tue Apr 03 19:59:01 2007
@@ -16,8 +16,119 @@
*/
#include "ver_graph.h"
+/**
+ * @ingroup Handles
+ * A handle of subroutine verification context.
+ */
+typedef const struct vf_SubContext *vf_SubContextHandle;
+/**
+ * @ingroup Handles
+ * A handle of subroutine verification context.
+ */
+typedef const struct vf_NodeStack *vf_NodeStackHandle;
+
+/**
+ * Subroutine info.
+ */
+struct vf_Sub
+{
+ /**
+ * A reference to the next subroutine.
+ */
+ vf_Sub *m_next;
+ /**
+ * A node which starts with subroutine entry point.
+ */
+ vf_NodeHandle m_entry;
+ /**
+ * A node which ends with ret instruction.
+ */
+ vf_NodeHandle m_ret;
+ /**
+ * A number of different jsr sequences to access
+ * this subroutine.
+ */
+ unsigned m_dupcount;
+ /**
+ * A number of nodes for this subroutine.
+ */
+ unsigned m_nodenum;
+ /**
+ * Subroutine nodes.
+ */
+ vf_NodeHandle *m_nodes;
+ /**
+ * Subroutine node copies. For each of m_nodenum nodes
+ * from m_nodes the (m_dupcount - 1) node copies follow
+ * one by one starting from this pointer.
+ * NULL when m_dupcount == 1.
+ */
+ vf_Node *m_copies;
+ /**
+ * For each of m_dupcount subroutine copies contain a return node for
+ * this copy.
+ */
+ vf_Node **m_following_nodes;
+ /**
+ * A number of edges between subroutine nodes.
+ */
+ unsigned m_out_edgenum;
+ /**
+ * A current duplication index.
+ */
+ unsigned m_index;
+};
+
+/**
+ * A stack of subsequent nodes representing a path traversing the graph, in
+ * particular a path to a ret node.
+ */
+struct vf_NodeStack
+{
+ /**
+ * A current node.
+ */
+ vf_Node *m_node;
+ /**
+ * An out stack depth of the node.
+ */
+ unsigned m_depth;
+ /**
+ * When a next stack element is created, points to the next stack element.
+ */
+ vf_NodeStackHandle m_next;
+
+ void Set(vf_NodeHandle node, unsigned depth)
+ {
+ m_node = (vf_Node *) node;
+ m_depth = depth;
+ m_next = NULL;
+ }
+};
+
/**
- * Verifier error codes.
+ * Aggregated subroutine data.
*/
-typedef Verifier_Result vf_Result;
+struct vf_SubContext
+{
+ /**
+ * Dedicated memory pool.
+ */
+ vf_Pool *m_pool;
+ /**
+ * A head of a list of subroutine descriptors.
+ */
+ vf_Sub *m_sub;
+ /**
+ * A start of a path to the current ret.
+ */
+ vf_NodeStackHandle m_path_start;
+ /**
+ * After the ret is resolved a ctx->m_map contains a
+ * correct input map for a node which follows jsr call. This is
+ * a pointer to the corresponding node stack. If this pointer is
+ * NULL we start from m_path_start stack entry.
+ */
+ vf_NodeStackHandle m_path_fork;
+};
diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\ver_utils.cpp 91/trunk/working_vm/vm/vmcore/src/verifier\ver_utils.cpp
--- 9/trunk/working_vm/vm/vmcore/src/verifier\ver_utils.cpp Tue Mar 20 19:34:53 2007
+++ 91/trunk/working_vm/vm/vmcore/src/verifier\ver_utils.cpp Tue Apr 03 19:59:04 2007
@@ -26,7 +26,7 @@
* Debug flag macros
*/
// Macro enable verifier memory trace
-#define VERIFY_TRACE_MEMORY 0
+#define VF_TRACE_MEMORY 0
/************************************************************
*********************** Hash class *************************
@@ -39,25 +39,21 @@ vf_Hash::vf_Hash ():HASH_SIZE( 127 ),
m_free( true )
{
m_pool = vf_create_pool();
- m_hash = (vf_HashEntry_t**) vf_alloc_pool_memory( m_pool,
- HASH_SIZE *
- sizeof
- ( vf_HashEntry_t
- * ) );
+ m_hash = (vf_HashEntry**)vf_palloc( m_pool,
+ HASH_SIZE *
+ sizeof(vf_HashEntry*) );
} // vf_Hash::vf_Hash
/**
* Hash table constructor.
*/
-vf_Hash::vf_Hash ( vf_VerifyPool_t * pool ):HASH_SIZE( 127 ),
+vf_Hash::vf_Hash ( vf_Pool *pool ):HASH_SIZE( 127 ),
m_free( false )
{
m_pool = pool;
- m_hash = (vf_HashEntry_t**) vf_alloc_pool_memory( m_pool,
- HASH_SIZE *
- sizeof
- ( vf_HashEntry_t
- * ) );
+ m_hash = (vf_HashEntry**)vf_palloc( m_pool,
+ HASH_SIZE *
+ sizeof(vf_HashEntry*) );
} // vf_Hash::vf_Hash
/**
@@ -71,9 +67,9 @@ vf_Hash::~vf_Hash ()
} // vf_Hash::vf_Hash
/**
- * Function checks key identity.
+ * Checks key identity.
*/
-inline bool vf_Hash::CheckKey( vf_HashEntry_t * hash_entry, // checked hash entry
+inline bool vf_Hash::CheckKey( vf_HashEntry *hash_entry, // checked hash entry
const char *key ) // checked key
{
if( !strcmp( hash_entry->key, key ) ) {
@@ -83,9 +79,9 @@ inline bool vf_Hash::CheckKey( vf_HashEn
} // vf_Hash::CheckKey( hash, key )
/**
- * Function checks key identity.
+ * Checks key identity.
*/
-inline bool vf_Hash::CheckKey( vf_HashEntry_t * hash_entry, // checked hash entry
+inline bool vf_Hash::CheckKey( vf_HashEntry *hash_entry, // checked hash entry
const char *key, // checked key
size_t len ) // key length
{
@@ -127,12 +123,12 @@ inline unsigned vf_Hash::HashFunc( const
/**
* Function looks up hash entry which is identical to current key.
*/
-inline vf_HashEntry_t *vf_Hash::Lookup( const char *key ) // hash key
+inline vf_HashEntry *vf_Hash::Lookup( const char *key ) // hash key
{
assert( key );
unsigned hash_index = HashFunc( key );
hash_index = hash_index % HASH_SIZE;
- vf_HashEntry_t *hash_entry = m_hash[hash_index];
+ vf_HashEntry *hash_entry = m_hash[hash_index];
while( hash_entry != NULL ) {
if( CheckKey( hash_entry, key ) ) {
return hash_entry;
@@ -145,14 +141,14 @@ inline vf_HashEntry_t *vf_Hash::Lookup(
/**
* Function looks up hash entry which is identical to current key.
*/
-inline vf_HashEntry_t *vf_Hash::Lookup( const char *key, // hash key
- unsigned len ) // key length
+inline vf_HashEntry *vf_Hash::Lookup( const char *key, // hash key
+ size_t len ) // key length
{
assert( key );
assert( len );
unsigned hash_index = HashFunc( key, len );
hash_index = hash_index % HASH_SIZE;
- vf_HashEntry_t *hash_entry = m_hash[hash_index];
+ vf_HashEntry *hash_entry = m_hash[hash_index];
while( hash_entry != NULL ) {
if( CheckKey( hash_entry, key, len ) ) {
return hash_entry;
@@ -165,13 +161,13 @@ inline vf_HashEntry_t *vf_Hash::Lookup(
/**
* Function creates hash entry which is identical to current key.
*/
-inline vf_HashEntry_t *vf_Hash::NewHashEntry( const char *key ) // hash key
+inline vf_HashEntry *vf_Hash::NewHashEntry( const char *key ) // hash key
{
// lookup type in hash
assert( key );
unsigned hash_index = HashFunc( key );
hash_index = hash_index % HASH_SIZE;
- vf_HashEntry_t *hash_entry = m_hash[hash_index];
+ vf_HashEntry *hash_entry = m_hash[hash_index];
while( hash_entry != NULL ) {
if( CheckKey( hash_entry, key ) ) {
return hash_entry;
@@ -181,13 +177,12 @@ inline vf_HashEntry_t *vf_Hash::NewHashE
// create key string
size_t len = strlen( key );
- char *hash_key = (char*)vf_alloc_pool_memory( m_pool, len + 1 );
+ char *hash_key = (char*)vf_palloc( m_pool, len + 1 );
memcpy( hash_key, key, len );
// create hash entry
hash_entry =
- (vf_HashEntry_t*) vf_alloc_pool_memory( m_pool,
- sizeof( vf_HashEntry_t ) );
+ (vf_HashEntry*)vf_palloc( m_pool, sizeof( vf_HashEntry ) );
hash_entry->key = hash_key;
hash_entry->next = m_hash[hash_index];
m_hash[hash_index] = hash_entry;
@@ -198,15 +193,15 @@ inline vf_HashEntry_t *vf_Hash::NewHashE
/**
* Function creates hash entry which is identical to current key.
*/
-inline vf_HashEntry_t *vf_Hash::NewHashEntry( const char *key, // hash key
- size_t len ) // key length
+inline vf_HashEntry *vf_Hash::NewHashEntry( const char *key, // hash key
+ size_t len ) // key length
{
// lookup type in hash
assert( key );
assert( len );
unsigned hash_index = HashFunc( key, len );
hash_index = hash_index % HASH_SIZE;
- vf_HashEntry_t *hash_entry = m_hash[hash_index];
+ vf_HashEntry *hash_entry = m_hash[hash_index];
while( hash_entry != NULL ) {
if( CheckKey( hash_entry, key, len ) ) {
return hash_entry;
@@ -215,13 +210,12 @@ inline vf_HashEntry_t *vf_Hash::NewHashE
}
// create key string
- char *hash_key = (char*)vf_alloc_pool_memory( m_pool, len + 1 );
+ char *hash_key = (char*)vf_palloc( m_pool, len + 1 );
memcpy( hash_key, key, len );
// create hash entry
hash_entry =
- (vf_HashEntry_t*) vf_alloc_pool_memory( m_pool,
- sizeof( vf_HashEntry_t ) );
+ (vf_HashEntry*)vf_palloc( m_pool, sizeof( vf_HashEntry ) );
hash_entry->key = hash_key;
hash_entry->next = m_hash[hash_index];
m_hash[hash_index] = hash_entry;
@@ -240,7 +234,6 @@ vf_TypePool::vf_TypePool():m_method( NUL
{
m_pool = vf_create_pool();
m_Hash = new vf_Hash ( m_pool );
- return;
} // vf_TypePool::vf_TypePool
/**
@@ -255,23 +248,21 @@ vf_TypePool::~vf_TypePool()
/**
* Function creates valid type which is identical to current class.
*/
-vf_ValidType_t *
+vf_ValidType *
vf_TypePool::NewType( const char *type, // class name
size_t len ) // name length
{
- vf_ValidType_t *result;
- vf_HashEntry_t *hash;
+ vf_ValidType *result;
+ vf_HashEntry *hash;
// find type in hash
hash = m_Hash->NewHashEntry( type, len );
if( hash->data ) {
- assert( ( (vf_ValidType_t*) hash->data )->number == 1 );
- return (vf_ValidType_t*) hash->data;
+ assert( ( (vf_ValidType*)hash->data )->number == 1 );
+ return (vf_ValidType*)hash->data;
}
// create and set type
- result =
- (vf_ValidType_t*) vf_alloc_pool_memory( m_pool,
- sizeof( vf_ValidType_t ) );
+ result = (vf_ValidType*)vf_palloc( m_pool, sizeof( vf_ValidType ) );
result->number = 1;
result->string[0] = hash->key;
// set type in hash
@@ -296,26 +287,23 @@ vf_type_string_compare( const void *type
/**
* Function creates valid type which is identical to an element of a given array type.
*/
-vf_ValidType_t *
-vf_TypePool::NewArrayElemType( vf_ValidType_t * array ) // array type
+vf_ValidType *
+vf_TypePool::NewArrayElemType( vf_ValidType *array ) // array type
{
- vf_ValidType_t *result;
- vf_HashEntry_t *hash;
+ vf_ValidType *result;
+ vf_HashEntry *hash;
// lookup type in hash
hash = m_Hash->NewHashEntry( &array->string[0][1] );
if( array->number == 1 && hash->data ) {
- assert( ( (vf_ValidType_t*) hash->data )->number == 1 );
- return (vf_ValidType_t*) hash->data;
+ assert( ( (vf_ValidType*)hash->data )->number == 1 );
+ return (vf_ValidType*)hash->data;
}
// create and set type
- result = (vf_ValidType_t*) vf_alloc_pool_memory( m_pool,
- sizeof
- ( vf_ValidType_t ) +
- ( array->number -
- 1 ) *
- sizeof( const char
- * ) );
+ result = (vf_ValidType*)vf_palloc( m_pool,
+ sizeof( vf_ValidType ) +
+ ( array->number -
+ 1 ) * sizeof( const char * ) );
result->number = array->number;
// set sting type
result->string[0] = hash->key;
@@ -337,7 +325,7 @@ vf_TypePool::NewArrayElemType( vf_ValidT
} // vf_TypePool::NewType
/**
- * Function dumps constraint collection in stream.
+ * Dumps constraint collection in stream.
*/
void
vf_TypePool::DumpTypeConstraints( ostream *out ) // output stream
@@ -345,100 +333,97 @@ vf_TypePool::DumpTypeConstraints( ostrea
if( out == NULL ) {
out = &cerr;
}
- for( vf_TypeConstraint_t * constraint = m_restriction;
- constraint; constraint = constraint->next ) {
+ for( vf_TypeConstraint *constraint = m_restriction;
+ constraint; constraint = constraint->m_next ) {
*out << "CONSTRAINT: have \""
- << constraint->source << "\" need \"" << constraint->
- target << "\" for method " <<
+ << constraint->m_source << "\" need \"" << constraint->
+ m_target << "\" for method " <<
class_get_name( method_get_class( m_method ) ) << "." <<
method_get_name( m_method ) << method_get_descriptor( m_method )
<< endl;
}
- return;
} // vf_TypePool::DumpTypeConstraints
/**
* Function returns the methods constraints array.
*/
-inline vf_TypeConstraint_t *
+inline vf_TypeConstraint *
vf_TypePool::GetClassConstraint()
{
return m_restriction;
} // vf_TypePool::GetClassConstraint
/**
- * Function sets current context method.
+ * Sets current context method.
*/
void
vf_TypePool::SetMethod( method_handler method )
{
// set method
m_method = method;
- return;
} // vf_TypePool::SetMethod
/**
- * Function sets restriction from target class to source class.
+ * Sets restriction from target class to source class.
*/
void
vf_TypePool::SetRestriction( const char *target, // target class name
const char *source, // source class name
unsigned short index, // constant pool index
- vf_CheckConstraint_t check_type ) // constraint check type
+ vf_CheckConstraint check_type ) // constraint check type
{
- vf_TypeConstraint_t *restriction;
+ vf_TypeConstraint *restriction;
// lookup restriction
for( restriction = m_restriction;
- restriction; restriction = restriction->next ) {
- if( restriction->target == target
- && restriction->source == source
- && restriction->index == index
- && restriction->check_type == check_type ) {
+ restriction; restriction = restriction->m_next ) {
+ if( restriction->m_target == target
+ && restriction->m_source == source
+ && restriction->m_index == index
+ && restriction->m_check_type == check_type ) {
// this restriction is already present
return;
}
}
// set restriction
- restriction = (vf_TypeConstraint_t*) vf_alloc_pool_memory( m_pool,
- sizeof
- ( vf_TypeConstraint_t ) );
- restriction->target = target;
- restriction->source = source;
- restriction->index = index;
- restriction->check_type = check_type;
- restriction->method = m_method;
- restriction->next = m_restriction;
+ restriction = (vf_TypeConstraint*)vf_palloc( m_pool,
+ sizeof
+ ( vf_TypeConstraint ) );
+ restriction->m_target = target;
+ restriction->m_source = source;
+ restriction->m_index = index;
+ restriction->m_check_type = check_type;
+ restriction->m_method = m_method;
+ restriction->m_next = m_restriction;
m_restriction = restriction;
// trace restriction
if( index ) {
- VERIFY_TRACE( "constraint", "CONSTRAINT: for class \""
- << class_get_name( method_get_class( m_method ) ) <<
- "\" CP index #" << index << " check access: have \"" <<
- source << "\" need \"" << target << "\" for method " <<
- class_get_name( method_get_class( m_method ) ) << "." <<
- method_get_name( m_method ) <<
- method_get_descriptor( m_method ) );
+ VF_TRACE( "constraint", "CONSTRAINT: for class \""
+ << class_get_name( method_get_class( m_method ) ) <<
+ "\" CP index #" << index << " check access: have \"" <<
+ source << "\" need \"" << target << "\" for method " <<
+ class_get_name( method_get_class( m_method ) ) << "." <<
+ method_get_name( m_method ) <<
+ method_get_descriptor( m_method ) );
} else {
- VERIFY_TRACE( "constraint", "CONSTRAINT: have \""
- << source << "\" need \"" << target << "\" for method "
- << class_get_name( method_get_class( m_method ) ) << "."
- << method_get_name( m_method ) <<
- method_get_descriptor( m_method ) );
+ VF_TRACE( "constraint", "CONSTRAINT: have \""
+ << source << "\" need \"" << target << "\" for method "
+ << class_get_name( method_get_class( m_method ) ) << "."
+ << method_get_name( m_method ) <<
+ method_get_descriptor( m_method ) );
}
- return;
} // vf_TypePool::SetRestriction
/**
- * Function checks types and create constraints if it's necessarily.
+ * Checks types and create constraints if it's necessarily.
*/
bool
-vf_TypePool::CheckTypes( vf_ValidType_t * required, // required type
- vf_ValidType_t * available, // available type
+vf_TypePool::CheckTypes( vf_ValidType *required, // required type
+ vf_ValidType *available, // available type
unsigned short index, // constant pool index
- vf_CheckConstraint_t check_type ) // constraint check type
+ vf_CheckConstraint check_type ) // constraint check type
{
unsigned index1, index2;
@@ -534,10 +519,10 @@ vf_TypePool::CheckTypes( vf_ValidType_t
}
return false;
default:
- LDIE( 39, "Verifier: CompareTypes: unknown check type in switch" );
+ VF_DIE( "CompareTypes: unknown check type in switch" );
return true;
}
- // unreachable code
+ // unreachable instr
assert( 0 );
} // vf_TypePool::CheckTypes
@@ -545,9 +530,9 @@ vf_TypePool::CheckTypes( vf_ValidType_t
* Function merges two valid types.
* Function returns NULL if vector wasn't merged.
*/
-vf_ValidType_t *
-vf_TypePool::MergeTypes( vf_ValidType_t * first, // first merged type
- vf_ValidType_t * second ) // second merged type
+vf_ValidType *
+vf_TypePool::MergeTypes( vf_ValidType *first, // first merged type
+ vf_ValidType *second ) // second merged type
{
// check null reference
if( first == NULL ) {
@@ -578,17 +563,12 @@ vf_TypePool::MergeTypes( vf_ValidType_t
return NULL;
}
// create merged type
- vf_ValidType_t *type = (vf_ValidType_t*) vf_alloc_pool_memory( m_pool,
- sizeof
- ( vf_ValidType_t )
- +
- ( count
- -
- 1 ) *
- sizeof
- ( const
- char
- * ) );
+ vf_ValidType *type = (vf_ValidType*)vf_palloc( m_pool,
+ sizeof( vf_ValidType )
+ + ( count -
+ 1 ) *
+ sizeof
+ ( const char * ) );
type->number = count;
// set type in ascending order of types string
@@ -615,74 +595,71 @@ vf_TypePool::MergeTypes( vf_ValidType_t
************************************************************/
/**
- * Function sets constraint for method in class loader verify data.
+ * Sets constraint for method in class loader verify data.
*/
static void
-vf_set_class_constraint( vf_TypeConstraint_t * collection, // constraint for the class
- vf_Context_t * ctex ) // verifier context
+vf_set_class_constraint( vf_TypeConstraint *collection, // constraint for the class
+ vf_ContextHandle ctx ) // verification context
{
// get class loader of current class
- classloader_handler class_loader =
- class_get_class_loader( ctex->m_class );
+ classloader_handler class_loader = class_get_class_loader( ctx->m_class );
// lock data modification
cl_acquire_lock( class_loader );
- vf_ClassLoaderData_t *cl_data =
- (vf_ClassLoaderData_t*) cl_get_verify_data_ptr( class_loader );
+ vf_ClassLoaderData *cl_data =
+ (vf_ClassLoaderData*) cl_get_verify_data_ptr( class_loader );
// create class loader data
if( cl_data == NULL ) {
- vf_VerifyPool_t *new_pool = vf_create_pool();
- cl_data = (vf_ClassLoaderData_t*) vf_alloc_pool_memory( new_pool,
- sizeof
- ( vf_ClassLoaderData_t ) );
+ vf_Pool *new_pool = vf_create_pool();
+ cl_data = (vf_ClassLoaderData*) vf_palloc( new_pool,
+ sizeof
+ ( vf_ClassLoaderData ) );
cl_data->pool = new_pool;
cl_data->string = new vf_Hash ( new_pool );
// set verify data for class loader
cl_set_verify_data_ptr( class_loader, cl_data );
}
- vf_VerifyPool_t *pool = cl_data->pool;
- vf_Hash_t *hash = cl_data->string;
+ vf_Pool *pool = cl_data->pool;
+ vf_Hash *hash = cl_data->string;
// create class constraints collection
- vf_TypeConstraint_t *save_collection = NULL;
- for( vf_TypeConstraint_t * restriction = collection;
- restriction; restriction = restriction->next ) {
+ vf_TypeConstraint *save_collection = NULL;
+ for( vf_TypeConstraint *restriction = collection;
+ restriction; restriction = restriction->m_next ) {
// create constraint
- vf_TypeConstraint_t *constraint =
- (vf_TypeConstraint_t*) vf_alloc_pool_memory( pool,
- sizeof
- ( vf_TypeConstraint_t ) );
+ vf_TypeConstraint *constraint =
+ (vf_TypeConstraint*)vf_palloc( pool,
+ sizeof( vf_TypeConstraint ) );
// create entry in string pool for target class
- vf_HashEntry_t *hash_entry =
- hash->NewHashEntry( restriction->target );
- constraint->target = hash_entry->key;
+ vf_HashEntry *hash_entry =
+ hash->NewHashEntry( restriction->m_target );
+ constraint->m_target = hash_entry->key;
// create entry in string pool for checked class
- hash_entry = hash->NewHashEntry( restriction->source );
- constraint->source = hash_entry->key;
- constraint->method = restriction->method;
- constraint->check_type = restriction->check_type;
- constraint->next = save_collection;
+ hash_entry = hash->NewHashEntry( restriction->m_source );
+ constraint->m_source = hash_entry->key;
+ constraint->m_method = restriction->m_method;
+ constraint->m_check_type = restriction->m_check_type;
+ constraint->m_next = save_collection;
save_collection = constraint;
}
assert( save_collection );
// save method verify data
- assert( class_get_verify_data_ptr( ctex->m_class ) == NULL );
- class_set_verify_data_ptr( ctex->m_class, save_collection );
+ assert( class_get_verify_data_ptr( ctx->m_class ) == NULL );
+ class_set_verify_data_ptr( ctx->m_class, save_collection );
// unlock data modification
cl_release_lock( class_loader );
- return;
} // vf_set_class_constraint
/**
- * Function receives class by given class name, loads it if it's needed.
+ * Receives class by given class name, loads it if it's needed.
*/
static class_handler
vf_resolve_class( const char *name, // resolved class name
bool need_load, // load flag
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
// get class name
if( name[0] == 'L' ) {
@@ -706,14 +683,13 @@ vf_resolve_class( const char *name,
}
// get class loader
- classloader_handler class_loader =
- class_get_class_loader( ctex->m_class );
+ classloader_handler class_loader = class_get_class_loader( ctx->m_class );
// receive class
class_handler result;
if( need_load ) {
// trace verifier loads
- VERIFY_TRACE( "load", "verify load: class " << name );
+ VF_TRACE( "load", "verify load: class " << name );
result = cl_load_class( class_loader, name );
} else {
result = cl_get_class( class_loader, name );
@@ -723,7 +699,7 @@ vf_resolve_class( const char *name,
} // vf_resolve_class
/**
- * Function checks if target class is super class of source class.
+ * Checks if target class is super class of source class.
*/
static inline bool
vf_is_super_class( class_handler source, // checked class
@@ -739,7 +715,7 @@ vf_is_super_class( class_handler source,
} // vf_is_super_class
/**
- * Function checks if target class is super interface of source class.
+ * Checks if target class is super interface of source class.
*/
static inline bool
vf_is_super_interface( class_handler source, // checked class
@@ -755,8 +731,8 @@ vf_is_super_interface( class_handler sou
for( unsigned index = 0;
index < class_get_superinterface_number( source ); index++ ) {
if( vf_is_super_interface
- ( class_get_superinterface( source, ( unsigned short )index ),
- target ) ) {
+ ( class_get_superinterface
+ ( source, ( unsigned short )index ), target ) ) {
return true;
}
}
@@ -765,7 +741,7 @@ vf_is_super_interface( class_handler sou
} // vf_is_super_interface
/**
- * Function checks method invocation conversion between source ans target classes.
+ * Checks method invocation conversion between source ans target classes.
*/
static bool
vf_is_param_valid( class_handler source, // checked class
@@ -788,7 +764,7 @@ vf_is_param_valid( class_handler source,
} // vf_is_param_valid
/**
- * Function checks narrow reference conversion between interface classes.
+ * Checks narrow reference conversion between interface classes.
* If class1 has method1 and class2 has method2, correspondingly,
* and methods are the same name and signature, function returns 1.
* If methods have different return types, function returns 0.
@@ -829,7 +805,7 @@ vf_check_interface_methods( class_handle
} // vf_check_interface_methods
/**
- * Function checks casting conversion between classes.
+ * Checks casting conversion between classes.
*/
static bool
vf_is_checkcast_valid( class_handler source, // checked class
@@ -883,7 +859,7 @@ vf_is_checkcast_valid( class_handler sou
} // vf_is_checkcast_valid
/**
- * Function checks assignment conversion between classes.
+ * Checks assignment conversion between classes.
*
* If strict flag is true, strict assignment compatible check is provided,
* else if strict flag is false, weak assignment compatible check is provided.
@@ -1002,7 +978,7 @@ vf_is_assign_valid( class_handler source
} // vf_is_assign_valid
/**
- * Function checks conversions between classes.
+ * Checks conversions between classes.
*/
static bool
vf_is_valid( class_handler source, // checked class
@@ -1030,7 +1006,7 @@ vf_is_valid( class_handler source,
return vf_is_super_class( source, current )
&& vf_is_super_class( current, target );
}
- LDIE( 40, "Verifier: vf_is_valid: invalid check type" );
+ VF_DIE( "vf_is_valid: invalid check type" );
return false;
} // vf_is_valid
@@ -1038,59 +1014,52 @@ vf_is_valid( class_handler source,
* Sets verifier error.
*/
static inline void
-vf_set_error( method_handler method, // failed method
- unsigned check, // failed check
- vf_Context_t * ctex ) // verifier context
+vf_set_error( unsigned check, // failed check
+ vf_Context *ctx ) // verification context
{
switch ( check ) {
case VF_CHECK_PARAM:
- VERIFY_REPORT_CLASS( ctex, method,
- "Incompatible argument for function" );
+ VF_REPORT( ctx, "Incompatible argument for function" );
return;
case VF_CHECK_ASSIGN:
- VERIFY_REPORT_CLASS( ctex, method,
- "Incompatible types for field assignment" );
+ VF_REPORT( ctx, "Incompatible types for field assignment" );
return;
case VF_CHECK_ASSIGN_WEAK:
- VERIFY_REPORT_CLASS( ctex, method,
- "Incompatible types for array assignment" );
+ VF_REPORT( ctx, "Incompatible types for array assignment" );
return;
case VF_CHECK_SUPER:
- VERIFY_REPORT_CLASS( ctex, method,
- "Exception class not a subclass of Throwable" );
+ VF_REPORT( ctx, "Exception class not a subclass of Throwable" );
return;
case VF_CHECK_ACCESS_FIELD:
- VERIFY_REPORT_CLASS( ctex, method, "Bad access to protected field" );
+ VF_REPORT( ctx, "Bad access to protected field" );
return;
case VF_CHECK_ACCESS_METHOD:
- VERIFY_REPORT_CLASS( ctex, method, "Bad access to protected method" );
+ VF_REPORT( ctx, "Bad access to protected method" );
return;
case VF_CHECK_DIRECT_SUPER:
- VERIFY_REPORT_CLASS( ctex, method,
- "Call to wrong initialization method" );
+ VF_REPORT( ctx, "Call to wrong initialization method" );
return;
case VF_CHECK_INVOKESPECIAL:
- VERIFY_REPORT_CLASS( ctex, method,
- "Incompatible object argument for invokespecial" );
+ VF_REPORT( ctx, "Incompatible object argument for invokespecial" );
return;
}
- LDIE( 41, "Verifier: vf_set_error: unknown check type" );
+ VF_DIE( "vf_set_error: unknown check type" );
} // vf_set_error
/**
* Checks some constraints without loading of needed classes.
*/
-static inline Verifier_Result
-vf_check_without_loading( vf_TypeConstraint_t * restriction, // checked constraint
- vf_Context_t * ctex ) // verifier context
+static inline vf_Result
+vf_check_without_loading( vf_TypeConstraint *restriction, // checked constraint
+ vf_Context *ctx ) // verification context
{
- switch ( restriction->check_type ) {
+ switch ( restriction->m_check_type ) {
case VF_CHECK_SUPER:
/**
* Extension for class java/lang/Object doesn't check
* because it's expected all references extend it.
*/
- if( restriction->target == ctex->m_vtype.m_object->string[0] ) {
+ if( restriction->m_target == ctx->m_vtype.m_object->string[0] ) {
// no need to check
return VER_OK;
}
@@ -1101,7 +1070,7 @@ vf_check_without_loading( vf_TypeConstra
* Extension for class java/lang/Object doesn't check
* because it's expected all references extend it.
*/
- if( restriction->target == ctex->m_vtype.m_object->string[0] ) {
+ if( restriction->m_target == ctx->m_vtype.m_object->string[0] ) {
// no need to check
return VER_OK;
}
@@ -1111,10 +1080,10 @@ vf_check_without_loading( vf_TypeConstra
* because it's expected all arrays extend it.
* Just check is source array.
*/
- if( restriction->target == ctex->m_vtype.m_array->string[0]
- && restriction->source[0] == '['
- && ( restriction->source[1] == '['
- || restriction->source[1] == 'L' ) ) {
+ if( restriction->m_target == ctx->m_vtype.m_array->string[0]
+ && restriction->m_source[0] == '['
+ && ( restriction->m_source[1] == '['
+ || restriction->m_source[1] == 'L' ) ) {
// no need to check
return VER_OK;
}
@@ -1124,9 +1093,10 @@ vf_check_without_loading( vf_TypeConstra
* interfaces doesn't check because it's expected all arrays extend it.
* Just check is source array.
*/
- if( ( restriction->target == ctex->m_vtype.m_clone->string[0]
- || restriction->target == ctex->m_vtype.m_serialize->string[0] )
- && restriction->source[0] == '[' ) {
+ if( ( restriction->m_target == ctx->m_vtype.m_clone->string[0]
+ || restriction->m_target ==
+ ctx->m_vtype.m_serialize->string[0] )
+ && restriction->m_source[0] == '[' ) {
// no need to check
return VER_OK;
}
@@ -1135,38 +1105,39 @@ vf_check_without_loading( vf_TypeConstra
* If method invocation conversion takes place between array and
* non-array reference, return error.
*/
- if( ( restriction->target[0] != '[' && restriction->source[0] == '[' )
- || ( restriction->target[0] != '['
- && restriction->source[0] == '[' ) ) {
- vf_set_error( ctex->m_method, VF_CHECK_PARAM, ctex );
+ if( ( restriction->m_target[0] != '['
+ && restriction->m_source[0] == '[' )
+ || ( restriction->m_target[0] != '['
+ && restriction->m_source[0] == '[' ) ) {
+ vf_set_error( VF_CHECK_PARAM, ctx );
return VER_ErrorIncompatibleArgument;
}
break;
case VF_CHECK_ASSIGN_WEAK:
// check assignment weak reference conversions
- if( restriction->source[0] == 'L' ) {
+ if( restriction->m_source[0] == 'L' ) {
return VER_OK;
}
- assert( restriction->source[0] == '[' );
+ assert( restriction->m_source[0] == '[' );
// go to the next check...
case VF_CHECK_ASSIGN:
// check assignment reference conversions
- if( restriction->source[0] == '[' ) {
+ if( restriction->m_source[0] == '[' ) {
// source class is array
- if( !memcmp( restriction->target, "Ljava/lang/Cloneable", 21 )
- || !memcmp( restriction->target, "Ljava/io/Serializable",
+ if( !memcmp( restriction->m_target, "Ljava/lang/Cloneable", 21 )
+ || !memcmp( restriction->m_target, "Ljava/io/Serializable",
22 ) ) {
// target class is java/lang/Cloneable
// or java/lang/Serializable interface
return VER_OK;
- } else if( restriction->target ==
- ctex->m_vtype.m_object->string[0] ) {
+ } else if( restriction->m_target ==
+ ctx->m_vtype.m_object->string[0] ) {
// target class is java/lang/Object
return VER_OK;
- } else if( restriction->target[0] != '[' ) {
+ } else if( restriction->m_target[0] != '[' ) {
// target class isn't array class
- vf_set_error( ctex->m_method, restriction->check_type, ctex );
+ vf_set_error( restriction->m_check_type, ctx );
return VER_ErrorIncompatibleArgument;
}
}
@@ -1180,20 +1151,19 @@ vf_check_without_loading( vf_TypeConstra
} // vf_check_without_loading
/**
- * Function checks constraint between loaded classes.
+ * Checks constraint between loaded classes.
* If any class isn't loaded, function returns unloaded error
* to store restriction to the class for future constraint check.
*/
-static inline Verifier_Result
-vf_check_constraint( vf_TypeConstraint_t * restriction, // checked constraint
- vf_Context_t * ctex ) // verifier context
+static inline vf_Result
+vf_check_constraint( vf_TypeConstraint *restriction, // checked constraint
+ vf_Context *ctx ) // verification context
{
/**
* Try to provide some checks without classes loading
*/
- if( !ctex->m_dump.m_verify ) {
- Verifier_Result result =
- vf_check_without_loading( restriction, ctex );
+ if( !ctx->m_verify_all ) {
+ vf_Result result = vf_check_without_loading( restriction, ctx );
if( result != VER_ClassNotLoaded ) {
// no need to check
return result;
@@ -1201,10 +1171,10 @@ vf_check_constraint( vf_TypeConstraint_t
}
// get target class handler
class_handler target =
- vf_resolve_class( restriction->target, false, ctex );
+ vf_resolve_class( restriction->m_target, false, ctx );
// get checked class
class_handler source =
- vf_resolve_class( restriction->source, false, ctex );
+ vf_resolve_class( restriction->m_source, false, ctx );
// check classes are loaded?
if( !target || !source ) {
return VER_ClassNotLoaded;
@@ -1217,41 +1187,41 @@ vf_check_constraint( vf_TypeConstraint_t
* To be compatible with those applications we should do full constraint
* checks only if -Xverify:all option is present in command line.
*/
- if( !ctex->m_dump.m_verify && class_is_interface_( target ) ) {
+ if( !ctx->m_verify_all && class_is_interface_( target ) ) {
// skip constraint check
return VER_OK;
}
// check restriction
if( !vf_is_valid
- ( source, target, ctex->m_class, restriction->check_type ) ) {
+ ( source, target, ctx->m_class, restriction->m_check_type ) ) {
// return error
- vf_set_error( ctex->m_method, restriction->check_type, ctex );
+ vf_set_error( restriction->m_check_type, ctx );
return VER_ErrorIncompatibleArgument;
}
return VER_OK;
} // vf_check_constraint
/**
- * Function checks access to protected field/method.
+ * Checks access to protected field/method.
* If function cannot check constraint because of any class isn't loaded,
* function return unloaded error to store restriction to the class
* for future constraint check.
*/
-Verifier_Result
+vf_Result
vf_check_access_constraint( const char *super_name, // name of super class
const char *instance_name, // name of instance class
unsigned short index, // constant pool index
- vf_CheckConstraint_t check_type, // access check type
- vf_Context_t * ctex ) // verifier context
+ vf_CheckConstraint check_type, // access check type
+ vf_Context *ctx ) // verification context
{
// get class handler of super class
- class_handler super_class = vf_resolve_class( super_name, false, ctex );
- if( !super_class || !vf_is_super_class( ctex->m_class, super_class ) ) {
+ class_handler super_class = vf_resolve_class( super_name, false, ctx );
+ if( !super_class || !vf_is_super_class( ctx->m_class, super_class ) ) {
// obtained class isn't super class of a given class, no need to check
return VER_OK;
}
// check if a class and a parent class is in the same package
- if( class_is_same_package( ctex->m_class, super_class ) ) {
+ if( class_is_same_package( ctx->m_class, super_class ) ) {
// class and parent class is in the same package,
// no need check access to protect members
return VER_OK;
@@ -1260,32 +1230,30 @@ vf_check_access_constraint( const char *
bool need_check = false;
if( check_type == VF_CHECK_ACCESS_FIELD ) {
field_handler field =
- class_resolve_nonstatic_field( ctex->m_class, index );
+ class_resolve_nonstatic_field( ctx->m_class, index );
if( !field ) {
// NoSuchFieldError or IllegalAccessError - nothing to check
- VERIFY_DEBUG( "verifying class " <<
- class_get_name( ctex->m_class )
- << " (method " << method_get_name( ctex->m_method )
- << method_get_descriptor( ctex->m_method )
- <<
- ") couldn't resolve field with constant pool index #"
- << index );
+ VF_DEBUG( "verifying class " << class_get_name( ctx->m_class )
+ << " (method " << method_get_name( ctx->m_method )
+ << method_get_descriptor( ctx->m_method )
+ <<
+ ") couldn't resolve field with constant pool index #"
+ << index );
return VER_OK;
}
if( field_is_protected( field ) ) {
need_check = true;
}
} else {
- method_handler method = class_resolve_method( ctex->m_class, index );
+ method_handler method = class_resolve_method( ctx->m_class, index );
if( !method || method_is_static( method ) ) {
// NoSuchMethodError or IllegalAccessError - nothing to check
- VERIFY_DEBUG( "verifying class " <<
- class_get_name( ctex->m_class )
- << " (method " << method_get_name( ctex->m_method )
- << method_get_descriptor( ctex->m_method )
- <<
- ") couldn't resolve method with constant pool index #"
- << index );
+ VF_DEBUG( "verifying class " << class_get_name( ctx->m_class )
+ << " (method " << method_get_name( ctx->m_method )
+ << method_get_descriptor( ctx->m_method )
+ <<
+ ") couldn't resolve method with constant pool index #"
+ << index );
return VER_OK;
}
if( method_is_protected( method ) ) {
@@ -1302,45 +1270,45 @@ vf_check_access_constraint( const char *
return VER_OK;
}
// get instance class
- class_handler instance = vf_resolve_class( instance_name, false, ctex );
+ class_handler instance = vf_resolve_class( instance_name, false, ctx );
if( !instance ) {
// instance class isn't loaded
return VER_ClassNotLoaded;
}
// check access constraint
- if( !vf_is_valid( instance, NULL, ctex->m_class, check_type ) ) {
+ if( !vf_is_valid( instance, NULL, ctx->m_class, check_type ) ) {
// return error
- vf_set_error( ctex->m_method, check_type, ctex );
+ vf_set_error( check_type, ctx );
return VER_ErrorIncompatibleArgument;
}
return VER_OK;
} // vf_check_access_constraint
/**
- * Function provides initial constraint checks for current class.
- * Function checks only loaded classes, and stores restriction for unloaded ones.
+ * Provides initial constraint checks for current class.
+ * Checks only loaded classes, and stores restriction for unloaded ones.
*/
-Verifier_Result
-vf_check_class_constraints( vf_Context_t * ctex ) // verifier context
+vf_Result
+vf_check_class_constraints( vf_Context *ctx ) // verification context
{
// set class restriction collection
- vf_TypeConstraint_t *last = NULL;
- vf_TypeConstraint_t *collection = ctex->m_type->GetClassConstraint();
+ vf_TypeConstraint *last = NULL;
+ vf_TypeConstraint *collection = ctx->m_type->GetClassConstraint();
// check constraints
- for( vf_TypeConstraint_t * constraint = collection;
- constraint; constraint = constraint->next ) {
+ for( vf_TypeConstraint *constraint = collection;
+ constraint; constraint = constraint->m_next ) {
// set context method
- ctex->m_method = constraint->method;
+ ctx->SetMethod( constraint->m_method );
// check constraint
- Verifier_Result result = vf_check_constraint( constraint, ctex );
+ vf_Result result = vf_check_constraint( constraint, ctx );
if( result == VER_OK ) {
// constraint checked, remove constraint from the collection
if( !last ) {
- collection = constraint->next;
+ collection = constraint->m_next;
} else {
- last->next = constraint->next;
+ last->m_next = constraint->m_next;
}
} else if( result != VER_ClassNotLoaded ) {
// return error
@@ -1352,54 +1320,54 @@ vf_check_class_constraints( vf_Context_t
}
if( collection ) {
// set constraint for further checking
- vf_set_class_constraint( collection, ctex );
+ vf_set_class_constraint( collection, ctx );
}
return VER_OK;
} // vf_check_class_constraints
/**
- * Function checks constraint for given class.
- * Function loads classes if it's needed.
+ * Checks a constraint for a given class. Loads classes if it's needed.
*/
-static inline Verifier_Result
-vf_force_check_constraint( vf_TypeConstraint_t * constraint, // class constraint
- vf_Context_t * ctex ) // verifier context
+static inline vf_Result
+vf_force_check_constraint( vf_TypeConstraint *constraint, // class constraint
+ vf_Context *ctx ) // verification context
{
// check if constraint is already verified
- if( constraint->check_type == VF_CHECK_NONE ) {
+ if( VF_CHECK_NONE == constraint->m_check_type ) {
// already verified
- VERIFY_TRACE( "constraint.checked", "verify constraint: have \""
- << constraint->source << "\" need \"" << constraint->
- target << "\" already done (check #1) for class " <<
- class_get_name( ctex->m_class ) );
+ VF_TRACE( "constraint.checked", "verify constraint: have \""
+ << constraint->m_source << "\" need \"" << constraint->
+ m_target << "\" already done (check #1) for class " <<
+ class_get_name( ctx->m_class ) );
return VER_OK;
}
// get target class
- class_handler target = vf_resolve_class( constraint->target, true, ctex );
+ class_handler target =
+ vf_resolve_class( constraint->m_target, true, ctx );
if( !target ) {
- VERIFY_DEBUG( "verifying class " << class_get_name( ctex->m_class )
- << " (method " << method_get_name( constraint->method )
- << method_get_descriptor( constraint->method )
- << ") couldn't load class \""
- << ( ( constraint->target[0] == 'L' )
- ? &( constraint->target[1] ) : constraint->target )
- << "\"" );
+ VF_DEBUG( "verifying class " << class_get_name( ctx->m_class )
+ << " (method " << method_get_name( constraint->m_method )
+ << method_get_descriptor( constraint->m_method )
+ << ") couldn't load class \""
+ << ( ( constraint->m_target[0] == 'L' )
+ ? &( constraint->m_target[1] ) : constraint->m_target )
+ << "\"" );
unsigned index = 0;
- while( constraint->target[index++] != 'L' ) {
- assert( constraint->target[index] != '\0' );
+ while( constraint->m_target[index++] != 'L' ) {
+ assert( constraint->m_target[index] != '\0' );
}
- VERIFY_REPORT( ctex, "Couldn't load class: "
- << &( constraint->target[index] ) );
+ VF_SET_CTX( ctx, "Couldn't load class: "
+ << &( constraint->m_target[index] ) );
return VER_ErrorLoadClass;
}
// check if constraint is already verified
- if( constraint->check_type == VF_CHECK_NONE ) {
+ if( VF_CHECK_NONE == constraint->m_check_type ) {
// already verified
- VERIFY_TRACE( "constraint.checked", "verify constraint: have \""
- << constraint->source << "\" need \"" << constraint->
- target << "\" already done (check #2) for class " <<
- class_get_name( ctex->m_class ) );
+ VF_TRACE( "constraint.checked", "verify constraint: have \""
+ << constraint->m_source << "\" need \"" << constraint->
+ m_target << "\" already done (check #2) for class " <<
+ class_get_name( ctx->m_class ) );
return VER_OK;
}
@@ -1410,84 +1378,86 @@ vf_force_check_constraint( vf_TypeConstr
* To be compatible with those applications we should do full constraint
* checks only if -Xverify:all option is present in command line.
*/
- if( !ctex->m_dump.m_verify && class_is_interface_( target ) ) {
+ if( !ctx->m_verify_all && class_is_interface_( target ) ) {
// skip constraint check
// reset constraint to successful
- constraint->check_type = VF_CHECK_NONE;
+ constraint->m_check_type = VF_CHECK_NONE;
return VER_OK;
}
// check if constraint is already verified
- if( constraint->check_type == VF_CHECK_NONE ) {
+ if( VF_CHECK_NONE == constraint->m_check_type ) {
// already verified
- VERIFY_TRACE( "constraint.checked", "verify constraint: have \""
- << constraint->source << "\" need \"" << constraint->
- target << "\" already done (check #3) for class " <<
- class_get_name( ctex->m_class ) );
+ VF_TRACE( "constraint.checked", "verify constraint: have \""
+ << constraint->m_source << "\" need \"" << constraint->
+ m_target << "\" already done (check #3) for class " <<
+ class_get_name( ctx->m_class ) );
return VER_OK;
}
// get stack reference class
- class_handler source = vf_resolve_class( constraint->source, true, ctex );
+ class_handler source =
+ vf_resolve_class( constraint->m_source, true, ctx );
if( !source ) {
- VERIFY_DEBUG( "verifying class " << class_get_name( ctex->m_class )
- << " (method " << method_get_name( constraint->method )
- << method_get_descriptor( constraint->method )
- << ") couldn't load class \""
- << ( ( constraint->source[0] == 'L' )
- ? &( constraint->source[1] ) : constraint->source )
- << "\"" );
+ VF_DEBUG( "verifying class " << class_get_name( ctx->m_class )
+ << " (method " << method_get_name( constraint->m_method )
+ << method_get_descriptor( constraint->m_method )
+ << ") couldn't load class \""
+ << ( ( constraint->m_source[0] == 'L' )
+ ? &( constraint->m_source[1] ) : constraint->m_source )
+ << "\"" );
unsigned index = 0;
- while( constraint->source[index++] != 'L' ) {
- assert( constraint->source[index] != '\0' );
+ while( constraint->m_source[index++] != 'L' ) {
+ assert( constraint->m_source[index] != '\0' );
}
- VERIFY_REPORT( ctex, "Couldn't load class: "
- << &( constraint->source[index] ) );
+ VF_SET_CTX( ctx, "Couldn't load class: "
+ << &( constraint->m_source[index] ) );
return VER_ErrorLoadClass;
}
// store constraint check type (it could be changed during validation check)
- vf_CheckConstraint_t check =
- ( vf_CheckConstraint_t ) constraint->check_type;
+ vf_CheckConstraint check =
+ ( vf_CheckConstraint ) constraint->m_check_type;
// check if constraint is already verified
if( check == VF_CHECK_NONE ) {
// already verified
- VERIFY_TRACE( "constraint.checked", "verify constraint: have \""
- << constraint->source << "\" need \"" << constraint->
- target << "\" already done (check #4) for class " <<
- class_get_name( ctex->m_class ) );
+ VF_TRACE( "constraint.checked", "verify constraint: have \""
+ << constraint->m_source << "\" need \"" << constraint->
+ m_target << "\" already done (check #4) for class " <<
+ class_get_name( ctx->m_class ) );
return VER_OK;
}
// check restriction
- if( !vf_is_valid( source, target, ctex->m_class, check ) ) {
+ if( !vf_is_valid( source, target, ctx->m_class, check ) ) {
// return error
- vf_set_error( constraint->method, check, ctex );
+ ctx->m_method = constraint->m_method;
+ vf_set_error( check, ctx );
return VER_ErrorIncompatibleArgument;
}
// reset constraint to successful
- constraint->check_type = VF_CHECK_NONE;
+ constraint->m_check_type = VF_CHECK_NONE;
return VER_OK;
} // vf_force_check_constraint
/**
* Function verifies class constraints.
*/
-static Verifier_Result
-vf_verify_class_constraints( vf_Context_t * ctex ) // verifier context
+static vf_Result
+vf_verify_class_constraints( vf_Context *ctx ) // verification context
{
// get method verify data
- vf_TypeConstraint_t *constraint =
- (vf_TypeConstraint_t*) class_get_verify_data_ptr( ctex->m_class );
+ vf_TypeConstraint *constraint =
+ (vf_TypeConstraint*)class_get_verify_data_ptr( ctx->m_class );
if( constraint == NULL ) {
return VER_OK;
}
// trace verified class
- VERIFY_TRACE( "class.constraint",
- "verify constraints: " << class_get_name( ctex->m_class ) );
+ VF_TRACE( "class.constraint",
+ "verify constraints: " << class_get_name( ctx->m_class ) );
// check method constraints
- Verifier_Result result = VER_OK;
- for( ; constraint; constraint = constraint->next ) {
- result = vf_force_check_constraint( constraint, ctex );
- if( result != VER_OK ) {
+ vf_Result result = VER_OK;
+ for( ; constraint; constraint = constraint->m_next ) {
+ result = vf_force_check_constraint( constraint, ctx );
+ if( VER_OK != result ) {
break;
}
}
@@ -1499,38 +1469,27 @@ vf_verify_class_constraints( vf_Context_
************************************************************/
/**
- * Function performs abend exit from VM.
- */
-void
-vf_error_func( VERIFY_SOURCE_PARAMS )
-{
- LDIE( 42, "{0} Verifier: abort!" << VERIFY_REPORT_SOURCE );
- exit( 1 );
-} // vf_error_func
-
-/**
* Function allocates an array in memory with elements initialized to zero.
*/
void *
vf_calloc_func( unsigned num, // number of elements
size_t size, // size of element
- VERIFY_SOURCE_PARAMS ) // debug info
+ VF_SOURCE_PARAMS ) // debug info
{
assert( num );
assert( size );
void *result = STD_CALLOC( num, size );
if( result == NULL ) {
// out of memory error
- LECHO( 41, "Verifier: {0}: out of memory" << "vf_calloc_func" );
- vf_error();
+ VF_DIE( "vf_calloc_func: out of memory" );
}
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory", VERIFY_REPORT_SOURCE
- << "(calloc) allocate memory addr: " << result
- << ", size: " << size *
- num << " (" << num << " by " << size << ")" );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory", VF_REPORT_SOURCE
+ << "(calloc) allocate memory addr: " << result
+ << ", size: " << size *
+ num << " (" << num << " by " << size << ")" );
+#endif // VF_TRACE_MEMORY
return result;
} // vf_calloc_func
@@ -1540,21 +1499,20 @@ vf_calloc_func( unsigned num, // numbe
*/
void *
vf_malloc_func( size_t size, // size of memory block
- VERIFY_SOURCE_PARAMS ) // debug info
+ VF_SOURCE_PARAMS ) // debug info
{
assert( size );
void *result = STD_MALLOC( size );
if( result == NULL ) {
// out of memory error
- LECHO( 41, "Verifier: {0}: out of memory" << "vf_malloc_func" );
- vf_error();
+ VF_DIE( "vf_malloc_func: out of memory" );
}
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory", VERIFY_REPORT_SOURCE
- << "(malloc) allocate memory addr: " << result
- << ", size: " << size );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory", VF_REPORT_SOURCE
+ << "(malloc) allocate memory addr: " << result
+ << ", size: " << size );
+#endif // VF_TRACE_MEMORY
return result;
} // vf_malloc_func
@@ -1565,21 +1523,20 @@ vf_malloc_func( size_t size, // size
void *
vf_realloc_func( void *pointer, // old pointer
size_t size, // size of memory block
- VERIFY_SOURCE_PARAMS ) // debug info
+ VF_SOURCE_PARAMS ) // debug info
{
assert( size );
void *result = STD_REALLOC( pointer, size );
if( result == NULL ) {
// out of memory error
- LECHO( 41, "Verifier: {0}: out of memory" << "vf_realloc_func" );
- vf_error();
+ VF_DIE( "vf_realloc_func: out of memory" );
}
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory", VERIFY_REPORT_SOURCE
- << "(realloc) reallocate memory from addr: " << pointer
- << " to addr: " << result << ", size: " << size );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory", VF_REPORT_SOURCE
+ << "(realloc) reallocate memory from addr: " << pointer
+ << " to addr: " << result << ", size: " << size );
+#endif // VF_TRACE_MEMORY
return result;
} // vf_realloc_func
@@ -1589,50 +1546,47 @@ vf_realloc_func( void *pointer, // old p
*/
void
vf_free_func( void *pointer, // free pointer
- VERIFY_SOURCE_PARAMS ) // debug info
+ VF_SOURCE_PARAMS ) // debug info
{
if( pointer ) {
STD_FREE( pointer );
} else {
- LECHO( 41, "Verifier: {0}: null pointer for free" << "vf_free_func" );
- vf_error();
+ VF_DIE( "vf_free_func: null pointer for free" );
}
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory", VERIFY_REPORT_SOURCE
- << "(free) free memory addr: " << ( void * )pointer );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory", VF_REPORT_SOURCE
+ << "(free) free memory addr: " << ( void * )pointer );
+#endif // VF_TRACE_MEMORY
- return;
} // vf_free_func
/**
* Function creates wide memory pool structure.
*/
-static inline vf_VerifyPoolInternal_t *
+static inline vf_PoolInternal *
vf_create_pool_element( size_t size, // initial pool size
- VERIFY_SOURCE_PARAMS ) // debug info
+ VF_SOURCE_PARAMS ) // debug info
{
- vf_VerifyPoolInternal_t *result;
+ vf_PoolInternal *result;
// create pool new entry and allocate memory for it
- result = (vf_VerifyPoolInternal_t*)
- vf_malloc_func( sizeof( vf_VerifyPoolInternal_t ) + size,
- VERIFY_SOURCE_ARGS1 );
- result->m_memory = (char*)result + sizeof( vf_VerifyPoolInternal_t );
+ result = (vf_PoolInternal*)
+ vf_malloc_func( sizeof( vf_PoolInternal ) + size, VF_SOURCE_ARGS1 );
+ result->m_memory = (char*)result + sizeof( vf_PoolInternal );
result->m_free = (char*)result->m_memory;
result->m_freesize = size;
result->m_next = NULL;
memset( result->m_memory, 0, size );
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool.element", VERIFY_REPORT_SOURCE
- << "(pool) create pool element: " << result
- << ", memory: " << result->
- m_memory << ", size: " << result->m_freesize );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool.element", VF_REPORT_SOURCE
+ << "(pool) create pool element: " << result
+ << ", memory: " << result->
+ m_memory << ", size: " << result->m_freesize );
+#endif // VF_TRACE_MEMORY
return result;
} // vf_create_pool_element
@@ -1640,31 +1594,29 @@ vf_create_pool_element( size_t size,
/**
* Function creates memory pool structure.
*/
-vf_VerifyPool_t *
-vf_create_pool_func( VERIFY_SOURCE_PARAMS )
+vf_Pool *
+vf_create_pool_func( VF_SOURCE_PARAMS )
{
// create new pool element
- vf_VerifyPoolInternal_t *pool =
- vf_create_pool_element( sizeof( vf_VerifyPool_t ) +
- VERIFY_POOL_ENTRY_SIZE,
- VERIFY_SOURCE_ARGS1 );
+ vf_PoolInternal *pool =
+ vf_create_pool_element( sizeof( vf_Pool ) + VF_POOL_ENTRY_SIZE,
+ VF_SOURCE_ARGS1 );
// set head pool
- vf_VerifyPool_t *result = (vf_VerifyPool_t*) pool->m_free;
- pool->m_memory = pool->m_free + sizeof( vf_VerifyPool_t );
+ vf_Pool *result = (vf_Pool*)pool->m_free;
+ pool->m_memory = pool->m_free + sizeof( vf_Pool );
pool->m_free = (char*)pool->m_memory;
- pool->m_freesize = VERIFY_POOL_ENTRY_SIZE;
+ pool->m_freesize = VF_POOL_ENTRY_SIZE;
result->m_pool = pool;
- result->m_memory =
- sizeof( vf_VerifyPoolInternal_t ) + sizeof( vf_VerifyPool_t )
- + VERIFY_POOL_ENTRY_SIZE;
+ result->m_memory = sizeof( vf_PoolInternal ) + sizeof( vf_Pool )
+ + VF_POOL_ENTRY_SIZE;
result->m_used = 0;
result->m_maxuse = 0;
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool", VERIFY_REPORT_SOURCE
- << "(pool) create pool: " << result );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool", VF_REPORT_SOURCE
+ << "(pool) create pool: " << result );
+#endif // VF_TRACE_MEMORY
return result;
} // vf_create_pool_func
@@ -1673,26 +1625,26 @@ vf_create_pool_func( VERIFY_SOURCE_PARAM
* Function allocates memory block in current pool.
*/
void *
-vf_alloc_pool_memory_func( vf_VerifyPool_t * hpool, // a given pool
- size_t size, // memory size
- VERIFY_SOURCE_PARAMS ) // debug info
+vf_palloc_func( vf_Pool *hpool, // a given pool
+ size_t size, // memory size
+ VF_SOURCE_PARAMS ) // debug info
{
const unsigned align = sizeof( void * ) - 1;
void *result = NULL;
- vf_VerifyPoolInternal_t *pool = hpool->m_pool;
+ vf_PoolInternal *pool = hpool->m_pool;
// align allocate size
size = ( size + align ) & ( ~align );
// find free space
- if( size > VERIFY_POOL_ENTRY_SIZE ) {
+ if( size > VF_POOL_ENTRY_SIZE ) {
// create new wide pool entry
- pool = vf_create_pool_element( size, VERIFY_SOURCE_ARGS1 );
+ pool = vf_create_pool_element( size, VF_SOURCE_ARGS1 );
pool->m_next = hpool->m_pool;
hpool->m_pool = pool;
- hpool->m_memory += sizeof( vf_VerifyPoolInternal_t ) + size;
+ hpool->m_memory += sizeof( vf_PoolInternal ) + size;
} else if( pool->m_freesize < size ) {
- vf_VerifyPoolInternal_t *last = NULL;
- vf_VerifyPoolInternal_t *entry = pool->m_next;
+ vf_PoolInternal *last = NULL;
+ vf_PoolInternal *entry = pool->m_next;
while( entry ) {
last = pool;
pool = entry;
@@ -1705,12 +1657,10 @@ vf_alloc_pool_memory_func( vf_VerifyPool
if( !entry ) {
// create new pool element
pool =
- vf_create_pool_element( VERIFY_POOL_ENTRY_SIZE,
- VERIFY_SOURCE_ARGS1 );
+ vf_create_pool_element( VF_POOL_ENTRY_SIZE, VF_SOURCE_ARGS1 );
pool->m_next = hpool->m_pool;
hpool->m_pool = pool;
- hpool->m_memory +=
- sizeof( vf_VerifyPoolInternal_t ) + VERIFY_POOL_ENTRY_SIZE;
+ hpool->m_memory += sizeof( vf_PoolInternal ) + VF_POOL_ENTRY_SIZE;
} else {
assert( last != NULL );
last->m_next = pool->m_next;
@@ -1724,38 +1674,37 @@ vf_alloc_pool_memory_func( vf_VerifyPool
pool->m_freesize -= size;
hpool->m_used += size;
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool", VERIFY_REPORT_SOURCE
- << "(pool) allocate memory in pool: " << hpool
- << ", memory: " << result << ", size: " << size
- << ", element: " << pool << ", free: " << pool->
- m_freesize );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool", VF_REPORT_SOURCE
+ << "(pool) allocate memory in pool: " << hpool
+ << ", memory: " << result << ", size: " << size
+ << ", element: " << pool << ", free: " << pool->m_freesize );
+#endif // VF_TRACE_MEMORY
return result;
-} // vf_alloc_pool_memory_func
+} // vf_palloc_func
/**
* Function cleans given pool.
*/
void
-vf_clean_pool_memory_func( vf_VerifyPool_t * hpool, // memory pool
- VERIFY_SOURCE_PARAMS ) // debug info
+vf_clean_pool_func( vf_Pool *hpool, // memory pool
+ VF_SOURCE_PARAMS ) // debug info
{
// set max used value
if( hpool->m_used > hpool->m_maxuse ) {
hpool->m_maxuse = hpool->m_used;
}
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool", VERIFY_REPORT_SOURCE
- << "(pool) clean pool: " << hpool
- << ", allocated: " << hpool->
- m_memory << ", used: " << hpool->m_used );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool", VF_REPORT_SOURCE
+ << "(pool) clean pool: " << hpool
+ << ", allocated: " << hpool->
+ m_memory << ", used: " << hpool->m_used );
+#endif // VF_TRACE_MEMORY
- vf_VerifyPoolInternal_t *pool = hpool->m_pool;
+ vf_PoolInternal *pool = hpool->m_pool;
while( pool ) {
// clean pool element space
unsigned used_size =
@@ -1765,58 +1714,56 @@ vf_clean_pool_memory_func( vf_VerifyPool
pool->m_freesize += used_size;
hpool->m_used -= used_size;
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool.element", VERIFY_REPORT_SOURCE
- << "(pool) clean pool element: " << pool
- << ", size: " << used_size );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool.element", VF_REPORT_SOURCE
+ << "(pool) clean pool element: " << pool
+ << ", size: " << used_size );
+#endif // VF_TRACE_MEMORY
// get next pool entry
pool = pool->m_next;
}
- return;
-} // vf_clean_pool_memory_func
+} // vf_clean_pool_func
/**
* Function releases memory from given pool.
*/
void
-vf_delete_pool_func( vf_VerifyPool_t * hpool, // memory pool
- VERIFY_SOURCE_PARAMS ) // debug info
+vf_delete_pool_func( vf_Pool *hpool, // memory pool
+ VF_SOURCE_PARAMS ) // debug info
{
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool", VERIFY_REPORT_SOURCE
- << "(pool) delete pool: " << hpool
- << ", allocated: " << hpool->m_memory
- << ", used: "
- << ( hpool->m_used >
- hpool->m_maxuse ? hpool->m_used : hpool->m_maxuse ) );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool", VF_REPORT_SOURCE
+ << "(pool) delete pool: " << hpool
+ << ", allocated: " << hpool->m_memory
+ << ", used: "
+ << ( hpool->m_used >
+ hpool->m_maxuse ? hpool->m_used : hpool->m_maxuse ) );
+#endif // VF_TRACE_MEMORY
- vf_VerifyPoolInternal_t *pool = hpool->m_pool;
+ vf_PoolInternal *pool = hpool->m_pool;
while( pool ) {
-#if VERIFY_TRACE_MEMORY
+#if VF_TRACE_MEMORY
// trace memory
- VERIFY_TRACE( "memory.pool.element", VERIFY_REPORT_SOURCE
- << "(pool) delete pool element: " << pool );
-#endif // VERIFY_TRACE_MEMORY
+ VF_TRACE( "memory.pool.element", VF_REPORT_SOURCE
+ << "(pool) delete pool element: " << pool );
+#endif // VF_TRACE_MEMORY
// store pool element
- vf_VerifyPoolInternal_t *entry = pool;
+ vf_PoolInternal *entry = pool;
// get next pool element
pool = pool->m_next;
// free pool element
- vf_free_func( entry, VERIFY_SOURCE_ARGS1 );
+ vf_free_func( entry, VF_SOURCE_ARGS1 );
}
- return;
} // vf_delete_pool_func
/**
- * Function provides final constraint checks for a given class.
+ * Provides final constraint checks for a given class.
*/
-Verifier_Result
+vf_Result
vf_verify_class_constraints( class_handler klass, // a given class
unsigned verifyAll, // verification level flag
char **message ) // verifier error message
@@ -1825,19 +1772,19 @@ vf_verify_class_constraints( class_handl
assert( message );
// create context
- vf_Context_t context;
+ vf_Context context;
context.m_class = klass;
- context.m_dump.m_verify = verifyAll ? 1 : 0;
+ context.m_verify_all = verifyAll ? true : false;
// verified constraint for a given method
- Verifier_Result result = vf_verify_class_constraints( &context );
+ vf_Result result = vf_verify_class_constraints( &context );
*message = context.m_error;
-#if _VERIFY_DEBUG
- if( result != VER_OK ) {
- VERIFY_DEBUG( "VerifyError: " << context.m_error );
+#if _VF_DEBUG
+ if( VER_OK != result ) {
+ VF_DEBUG( "VerifyError: " << context.m_error );
}
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
return result;
} // vf_verify_class_constraints
@@ -1848,9 +1795,8 @@ vf_verify_class_constraints( class_handl
void
vf_release_verify_data( void *data )
{
- vf_ClassLoaderData_t *cl_data = (vf_ClassLoaderData_t*) data;
+ vf_ClassLoaderData *cl_data = (vf_ClassLoaderData*) data;
delete cl_data->string;
vf_delete_pool( cl_data->pool );
- return;
} // vf_release_verify_data
diff -upN 9/trunk/working_vm/vm/vmcore/src/verifier\Verifier.cpp 91/trunk/working_vm/vm/vmcore/src/verifier\Verifier.cpp
--- 9/trunk/working_vm/vm/vmcore/src/verifier\Verifier.cpp Tue Mar 20 19:34:52 2007
+++ 91/trunk/working_vm/vm/vmcore/src/verifier\Verifier.cpp Tue Apr 03 19:59:03 2007
@@ -26,21 +26,21 @@
* Debug flag macros
*/
// Macro sets verification only for defined class
-#define VERIFY_CLASS 0
+#define VF_CLASS 0
// Macro sets verification only for defined method
-#define VERIFY_METHOD 0
+#define VF_METHOD 0
/**
- * Function parse bytecode, determines code instructions, fills code array and
+ * Parses bytecode, determines instruction boundaries and
* provides checks of simple verifications.
*/
-static Verifier_Result vf_parse_bytecode( vf_Context_t * context ); // verifier context
+static vf_Result vf_parse_bytecode( vf_Context *ctx ); // verification context
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
/**
- * Function prints code instruction array in stream.
+ * Prints code instruction array in stream.
*/
-void vf_dump_bytecode( vf_Context_t * context ); // verifier context
+void vf_dump_bytecode( vf_ContextHandle ); // verification context
/**
* Array of opcode names. Available in debug mode.
@@ -51,18 +51,18 @@ const char *vf_opcode_names[256] = {
"FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH",
"LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD", "ALOAD",
"ILOAD_0", "ILOAD_1", "ILOAD_2", "ILOAD_3", "LLOAD_0", "LLOAD_1",
- "LLOAD_2",
+ "LLOAD_2",
"LLOAD_3", "FLOAD_0", "FLOAD_1", "FLOAD_2", "FLOAD_3", "DLOAD_0",
- "DLOAD_1",
+ "DLOAD_1",
"DLOAD_2", "DLOAD_3", "ALOAD_0", "ALOAD_1", "ALOAD_2", "ALOAD_3",
- "IALOAD",
+ "IALOAD",
"LALOAD", "FALOAD", "DALOAD", "AALOAD", "BALOAD", "CALOAD", "SALOAD",
"ISTORE", "LSTORE", "FSTORE", "DSTORE", "ASTORE", "ISTORE_0", "ISTORE_1",
"ISTORE_2", "ISTORE_3", "LSTORE_0", "LSTORE_1", "LSTORE_2", "LSTORE_3",
"FSTORE_0", "FSTORE_1", "FSTORE_2", "FSTORE_3", "DSTORE_0", "DSTORE_1",
"DSTORE_2", "DSTORE_3", "ASTORE_0", "ASTORE_1", "ASTORE_2", "ASTORE_3",
"IASTORE", "LASTORE", "FASTORE", "DASTORE", "AASTORE", "BASTORE",
- "CASTORE",
+ "CASTORE",
"SASTORE", "POP", "POP2", "DUP", "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1",
"DUP2_X2", "SWAP", "IADD", "LADD", "FADD", "DADD", "ISUB", "LSUB", "FSUB",
"DSUB", "IMUL", "LMUL", "FMUL", "DMUL", "IDIV", "LDIV", "FDIV", "DDIV",
@@ -73,83 +73,67 @@ const char *vf_opcode_names[256] = {
"FCMPG", "DCMPL", "DCMPG", "IFEQ", "IFNE", "IFLT", "IFGE", "IFGT", "IFLE",
"IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT",
"IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE", "GOTO", "JSR", "RET",
- "TABLESWITCH",
+ "TABLESWITCH",
"LOOKUPSWITCH", "IRETURN", "LRETURN", "FRETURN", "DRETURN", "ARETURN",
"RETURN", "GETSTATIC", "PUTSTATIC", "GETFIELD", "PUTFIELD",
- "INVOKEVIRTUAL",
+ "INVOKEVIRTUAL",
"INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", "_OPCODE_UNDEFINED",
"NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", "ATHROW", "CHECKCAST",
"INSTANCEOF", "MONITORENTER", "MONITOREXIT", "WIDE", "MULTIANEWARRAY",
"IFNULL", "IFNONNULL", "GOTO_W", "JSR_W",
};
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
/**
- * Function provides method bytecode verifications.
+ * Provides method bytecode verifications.
*/
-static Verifier_Result
-vf_verify_method_bytecode( vf_Context_t * ctex ) // verifier context
+static vf_Result
+vf_verify_method_bytecode( vf_Context *ctx ) // verification context
{
- unsigned len;
- Verifier_Result result = VER_OK;
+ vf_Result result = VER_OK;
- VERIFY_TRACE( "method",
- "verify method: " << class_get_name( ctex->m_class )
- << "." << method_get_name( ctex->
- m_method ) <<
- method_get_descriptor( ctex->m_method ) );
-
- /**
- * Getting bytecode array and its length
- */
- if( !( len = method_get_code_length( ctex->m_method ) ) ) {
- return VER_OK;
- }
+ VF_TRACE( "method", VF_REPORT_CTX( ctx ) << "verifying method" );
/**
* Set method for type pool
*/
- ctex->m_type->SetMethod( ctex->m_method );
+ ctx->m_type->SetMethod( ctx->m_method );
- /**
- * Allocate memory for code and bytecode annotations.
- */
- ctex->m_code = (vf_Code_t*) vf_alloc_pool_memory( ctex->m_pool,
- len *
- sizeof
- ( vf_Code_t ) );
- ctex->m_bc =
- (vf_BCode_t*) vf_alloc_pool_memory( ctex->m_pool,
- len * sizeof( vf_BCode_t ) );
+ // get method signature
+ const char *descr = method_get_descriptor( ctx->m_method );
- /**
- * Parse bytecode, fill instruction code.
- */
- result = vf_parse_bytecode( ctex );
- if( result != VER_OK ) {
+ // parse method signature
+ vf_parse_description( descr, &ctx->m_method_inlen,
+ &ctx->m_method_outlen );
+ vf_set_description_vector( descr, ctx->m_method_inlen, 0,
+ ctx->m_method_outlen, &ctx->m_method_invector,
+ &ctx->m_method_outvector, ctx );
+
+ // parse bytecode, fill instruction instr
+ result = vf_parse_bytecode( ctx );
+ if( VER_OK != result ) {
goto labelEnd_verifyClassBytecode;
}
- /**
- * Build bytecode graph
- */
- result = vf_create_graph( ctex );
- if( ctex->m_dump.m_with_subroutine ) {
- result = VER_NoSupportJSR;
+ // build a control flow graph
+ result = vf_create_graph( ctx );
+ if( VER_OK != result ) {
goto labelEnd_verifyClassBytecode;
- result = vf_inline_subroutines( ctex );
- if( VER_OK != result ) {
- goto labelEnd_verifyClassBytecode;
- }
}
- // check control and data flow
- result = vf_check_graph( ctex );
- if( result != VER_OK ) {
+
+ result = vf_check_graph( ctx );
+ if( VER_OK != result ) {
goto labelEnd_verifyClassBytecode;
}
labelEnd_verifyClassBytecode:
- vf_free_graph( ctex );
+ VF_TRACE( "method", VF_REPORT_CTX( ctx ) << "method statistics: "
+ << " rets: " << ctx->m_retnum
+ << ", length: " << ctx->m_len
+ << ", handlers: " << ctx->m_handlers
+ << ", max stack: " << ctx->m_maxstack
+ << ", max locals: " << ctx->m_maxlocal );
+ vf_free_graph( ctx );
return result;
} // vf_verify_method_bytecode
@@ -158,45 +142,41 @@ vf_verify_method_bytecode( vf_Context_t
************************************************************/
/**
- * Function creates array of instruction branch offsets.
+ * Creates array of instruction branch offsets.
*/
static inline void
-vf_create_code_offset( vf_Code_t * code, // given instruction
- unsigned offcount, // number of offets
- vf_VerifyPool_t * pool ) // memory pool
-{
- assert( !code->m_off );
- code->m_off =
- ( unsigned * )vf_alloc_pool_memory( pool,
- offcount * sizeof( unsigned ) );
- code->m_offcount = offcount;
- return;
+vf_create_instr_offset( vf_Instr *instr, // given instruction
+ unsigned offcount, // number of offets
+ vf_Pool *pool ) // memory pool
+{
+ assert( !instr->m_off );
+ instr->m_off =
+ ( unsigned * )vf_palloc( pool, offcount * sizeof( unsigned ) );
+ instr->m_offcount = offcount;
} // vf_create_instruction_offset
/**
- * Function sets code branch offset.
+ * Sets instruction branch offset.
*/
static inline void
-vf_set_code_offset( vf_Code_t * code, // given instruction
- unsigned offnum, // offset index in array
- unsigned value ) // offset value
+vf_set_instr_offset( vf_InstrHandle instr, // given instruction
+ unsigned offnum, // offset index in array
+ unsigned value ) // offset value
{
- assert( code->m_off && offnum < code->m_offcount );
- code->m_off[offnum] = value;
- return;
+ assert( instr->m_off && offnum < instr->m_offcount );
+ instr->m_off[offnum] = value;
} // vf_set_instruction_offset
/**
* Function creates a single branch.
*/
static inline void
-vf_set_single_branch_offset( vf_Code_t * code, // given instruction
+vf_set_single_branch_offset( vf_Instr *instr, // given instruction
unsigned value, // offset value
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
- vf_create_code_offset( code, 1, pool );
- vf_set_code_offset( code, 0, value );
- return;
+ vf_create_instr_offset( instr, 1, pool );
+ vf_set_instr_offset( instr, 0, value );
} // vf_set_single_instruction_offset
/************************************************************
@@ -204,105 +184,105 @@ vf_set_single_branch_offset( vf_Code_t *
************************************************************/
/**
- * Function sets stack modifier attribute for given code instruction.
+ * Sets stack modifier attribute for given code instruction.
*/
static inline void
-vf_set_stack_modifier( vf_Code_t * code, // code instruction
+vf_set_stack_modifier( vf_Instr *instr, // code instruction
int modify ) // stack modifier value
{
// set stack modifier for instruction
- code->m_stack = ( short )modify;
- return;
+ instr->m_stack = ( short )modify;
} // vf_set_stack_modifier
/**
- * Function sets minimal stack attribute for given code instruction.
+ * Sets minimal stack attribute for given code instruction.
*/
static inline void
-vf_set_min_stack( vf_Code_t * code, // code instruction
+vf_set_min_stack( vf_Instr *instr, // code instruction
unsigned min_stack ) // minimal stack value
{
// set minimal stack for instruction
- code->m_minstack = ( unsigned short )min_stack;
- return;
+ instr->m_minstack = ( unsigned short )min_stack;
} // vf_set_min_stack
/**
- * Function sets basic block attribute for instruction.
+ * The length of the longest instruction except switches.
+ */
+const unsigned GOTO_W_LEN = 5;
+/**
+ * Sets basic block attribute for instruction.
*/
static inline void
-vf_set_basic_block_flag( vf_BCode_t * code ) // instruction
+vf_set_basic_block_flag( unsigned short pc, vf_ContextHandle ctx )
{
+ assert( pc < ctx->m_len + GOTO_W_LEN );
// set begin of basic block for instruction
- code->m_mark = 1;
- return;
+ ctx->m_bc[pc].m_is_bb_start = true;
} // vf_set_basic_block_flag
+
/**
* Sets flags for the instruction.
*/
static inline void
-vf_set_code_type( vf_Code_t * code, // instruction
- vf_CodeType type ) // given flags
+vf_set_instr_type( vf_Instr *instr, // instruction
+ vf_InstrType type ) // given flags
{
// set flag for instruction
- code->m_type = type;
- return;
-} // vf_set_code_type
+ instr->m_type = type;
+} // vf_set_instr_type
/**
- * Function checks local number.
+ * Checks local number.
*/
-static inline Verifier_Result
+static inline vf_Result
vf_check_local_var_number( unsigned local, // local number
- unsigned maxlocal, // max local
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
// check local variable number
- if( local >= maxlocal ) {
- VERIFY_REPORT_METHOD( ctex, "Incorrect usage of local variable" );
+ if( local >= ctx->m_maxlocal ) {
+ VF_REPORT( ctx, "Incorrect usage of local variable" );
return VER_ErrorLocals;
}
return VER_OK;
} // vf_check_local_var_number
/**
- * Function checks branch offset.
+ * Checks branch offset.
*/
-static inline Verifier_Result
+static inline vf_Result
vf_check_branch_offset( int offset, // given instruction offset
- unsigned maxlen, // bytecode length
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- if( offset < 0 || ( unsigned )offset >= maxlen ) {
- VERIFY_REPORT_METHOD( ctex,
- "Instruction branch offset is out of range" );
+ if( offset < 0 || ( unsigned )offset >= ctx->m_len ) {
+ VF_REPORT( ctx, "Instruction branch offset is out of range" );
return VER_ErrorBranch;
}
+ ctx->m_bc[offset].m_is_bb_start = true;
return VER_OK;
} // vf_check_branch_offset
/**
* Function parses local variable number from instruction bytecode.
*/
-static inline unsigned
-vf_get_local_var_number( vf_Code_t * code, // code instruction
+static inline unsigned short
+vf_get_local_var_number( vf_InstrHandle instr, // code instruction
unsigned char *bytecode, // method bytecode
unsigned *index_p, // index in bytecode array
bool wide_flag ) // if this is a wide instruction
{
- unsigned local;
+ unsigned short local;
if( ( wide_flag ) ) {
// get number of local variable
local =
- ( unsigned )( ( bytecode[( *index_p )] << 8 ) |
- ( bytecode[( *index_p ) + 1] ) );
+ ( unsigned short )( ( bytecode[( *index_p )] << 8 ) |
+ ( bytecode[( *index_p ) + 1] ) );
// skip parameter (u2)
( *index_p ) += 2;
} else {
// get number of local variable
- local = ( unsigned )bytecode[( *index_p )];
+ local = ( unsigned short )bytecode[( *index_p )];
// skip parameter (u1)
( *index_p )++;
}
@@ -310,7 +290,7 @@ vf_get_local_var_number( vf_Code_t * cod
} // vf_get_local_var_number
/**
- * Function receives half word (2 bytes) instruction branch offset
+ * Receives half word (2 bytes) instruction branch offset
* value from bytecode array.
*/
static inline int
@@ -329,7 +309,7 @@ vf_get_hword_offset( unsigned code_pc,
} // vf_get_hword_offset
/**
- * Function receives word (4 bytes) instruction branch offset value from bytecode array.
+ * Receives word (4 bytes) instruction branch offset value from bytecode array.
*/
static inline int
vf_get_word_offset( unsigned code_pc, // instruction offset in bytecode array
@@ -349,94 +329,94 @@ vf_get_word_offset( unsigned code_pc,
} // vf_get_word_offset
/**
- * Function receives half word (2 bytes) branch offset from bytecode array,
+ * Receives half word (2 bytes) branch offset from bytecode array,
* sets into instruction and returns it.
*/
static inline int
-vf_get_single_hword_branch_offset( vf_Code_t * code, // instruction
+vf_get_single_hword_branch_offset( vf_Instr *instr, // instruction
unsigned code_pc, // offset in bytecode array
unsigned char *bytecode, // bytecode array
unsigned *index_p, // offset index in bytecode array
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// get first branch offset
int offset = vf_get_hword_offset( code_pc, bytecode, index_p );
// create and set edge branch for instruction
- vf_set_single_branch_offset( code, offset, pool );
+ vf_set_single_branch_offset( instr, offset, pool );
return offset;
} // vf_get_single_hword_branch_offset
/**
- * Function receives word (4 bytes) branch offset from bytecode array,
+ * Receives word (4 bytes) branch offset from bytecode array,
* sets into instruction and returns it.
*/
static inline int
-vf_get_single_word_branch_offset( vf_Code_t * code, // instruction
+vf_get_single_word_branch_offset( vf_Instr *instr, // instruction
unsigned code_pc, // offset in bytecode array
unsigned char *bytecode, // bytecode array
unsigned *index_p, // offset index in bytecode array
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// get first branch offset
int offset = vf_get_word_offset( code_pc, bytecode, index_p );
// create and set edge branch for instruction
- vf_set_single_branch_offset( code, offset, pool );
+ vf_set_single_branch_offset( instr, offset, pool );
return offset;
} // vf_get_single_word_branch_offset
/**
- * Function receives half word (2 bytes) branch offset from bytecode array and
+ * Receives half word (2 bytes) branch offset from bytecode array and
* sets received offset and next instruction offset into instruction.
* Function returns received offset.
*/
static inline int
-vf_get_double_hword_branch_offset( vf_Code_t * code, // instruction
+vf_get_double_hword_branch_offset( vf_Instr *instr, // instruction
unsigned code_pc, // instruction offset in bytcode array
unsigned char *bytecode, // bytecode array
unsigned *index_p, // offset index in bytecode array
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// get first branch offset
int offset = vf_get_hword_offset( code_pc, bytecode, index_p );
// create and set edge branches for instruction
- vf_create_code_offset( code, 2, pool );
+ vf_create_instr_offset( instr, 2, pool );
// set first edge branch for instruction
- vf_set_code_offset( code, 0, offset );
+ vf_set_instr_offset( instr, 0, offset );
// set second edge branch for instruction
- vf_set_code_offset( code, 1, ( *index_p ) );
+ vf_set_instr_offset( instr, 1, ( *index_p ) );
return offset;
} // vf_get_double_hword_branch_offset
/**
- * Function receives word (4 bytes) branch offset from bytecode array and
+ * Receives word (4 bytes) branch offset from bytecode array and
* sets received offset and next instruction offset into instruction.
* Function returns received offset.
*/
static inline int
-vf_get_double_word_branch_offset( vf_Code_t * code, // instruction
+vf_get_double_word_branch_offset( vf_Instr *instr, // instruction
unsigned code_pc, // instruction offset in bytcode array
unsigned char *bytecode, // bytecode array
unsigned *index_p, // offset index in bytecode array
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// get first branch offset
int offset = vf_get_word_offset( code_pc, bytecode, index_p );
// create and set edge branches for instruction
- vf_create_code_offset( code, 2, pool );
+ vf_create_instr_offset( instr, 2, pool );
// set first edge branch for instruction
- vf_set_code_offset( code, 0, offset );
+ vf_set_instr_offset( instr, 0, offset );
// set second edge branch for instruction
- vf_set_code_offset( code, 1, ( *index_p ) );
+ vf_set_instr_offset( instr, 1, ( *index_p ) );
return offset;
} // vf_get_double_word_branch_offset
/**
- * Function receives tableswitch branch from bytecode array and
+ * Receives tableswitch branch from bytecode array and
* sets received offset into instruction.
* Function returns received branch.
*/
static inline int
-vf_get_tableswitch_alternative( vf_Code_t * code, // instruction
+vf_get_tableswitch_alternative( vf_InstrHandle instr, // instruction
unsigned code_pc, // offset in bytcode array
unsigned alternative, // number of tableswitch branch
unsigned char *bytecode, // bytecode array
@@ -445,21 +425,21 @@ vf_get_tableswitch_alternative( vf_Code_
// get first branch offset
int offset = vf_get_word_offset( code_pc, bytecode, index_p );
// set first edge branch for instruction
- vf_set_code_offset( code, alternative, offset );
+ vf_set_instr_offset( instr, alternative, offset );
return offset;
} // vf_get_tableswitch_alternative
/**
- * Function receives tableswitch alternatives from bytecode array and
+ * Receives tableswitch alternatives from bytecode array and
* sets them into instruction.
* Function returns number of alternatives.
*/
static inline int
-vf_set_tableswitch_offsets( vf_Code_t * code, // instruction
+vf_set_tableswitch_offsets( vf_Instr *instr, // instruction
unsigned code_pc, // instruction offset in bytecode array
unsigned *index_p, // offset index in bytecode array
unsigned char *bytecode, // bytecode array
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// skip padding
unsigned default_off = ( ( *index_p ) + 0x3 ) & ( ~0x3U );
@@ -471,13 +451,13 @@ vf_set_tableswitch_offsets( vf_Code_t *
int high = vf_get_word_offset( code_pc, bytecode, &index );
int number = high - low + 2;
// create tableswitch branches
- vf_create_code_offset( code, number, pool );
+ vf_create_instr_offset( instr, number, pool );
// set default offset
- vf_get_tableswitch_alternative( code, code_pc, 0, bytecode,
+ vf_get_tableswitch_alternative( instr, code_pc, 0, bytecode,
&default_off );
// set another instruction offsets
for( int count = 1; count < number; count++ ) {
- vf_get_tableswitch_alternative( code, code_pc, count, bytecode,
+ vf_get_tableswitch_alternative( instr, code_pc, count, bytecode,
&index );
}
// set index next instruction
@@ -486,17 +466,17 @@ vf_set_tableswitch_offsets( vf_Code_t *
} // vf_set_tableswitch_offsets
/**
- * Function receives lookupswitch alternatives from bytecode array and
+ * Receives lookupswitch alternatives from bytecode array and
* sets them into instruction.
* Function returns number of alternatives.
*/
-static inline Verifier_Result
-vf_set_lookupswitch_offsets( vf_Code_t * code, // instruction
+static inline vf_Result
+vf_set_lookupswitch_offsets( vf_Instr *instr, // instruction
unsigned code_pc, // instruction offset in bytecode
unsigned *index_p, // offset index in bytecode array
unsigned char *bytecode, // array of bytecode
unsigned *branch_p, // number of alternatives
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
// skip padding
unsigned default_off = ( ( *index_p ) + 0x3 ) & ( ~0x3U );
@@ -507,9 +487,9 @@ vf_set_lookupswitch_offsets( vf_Code_t *
int number = vf_get_word_offset( 0, bytecode, &index ) + 1;
*branch_p = number;
// create and tableswitch branches
- vf_create_code_offset( code, number, ctex->m_pool );
+ vf_create_instr_offset( instr, number, ctx->m_pool );
// set default offset
- vf_get_tableswitch_alternative( code, code_pc, 0, bytecode,
+ vf_get_tableswitch_alternative( instr, code_pc, 0, bytecode,
&default_off );
// set another instruction offsets
int old_key = INT_MIN;
@@ -519,12 +499,12 @@ vf_set_lookupswitch_offsets( vf_Code_t *
if( old_key < key ) {
old_key = key;
} else if( key != INT_MIN ) {
- VERIFY_REPORT_METHOD( ctex,
- "Instruction lookupswitch has unsorted key values" );
+ VF_REPORT( ctx,
+ "Instruction lookupswitch has unsorted key values" );
return VER_ErrorInstruction;
}
// get lookupswitch alternative and set offset to instruction
- vf_get_tableswitch_alternative( code, code_pc, count, bytecode,
+ vf_get_tableswitch_alternative( instr, code_pc, count, bytecode,
&index );
}
// set index next instruction
@@ -537,111 +517,104 @@ vf_set_lookupswitch_offsets( vf_Code_t *
************************************************************/
/**
- * Function sets check type for a given stack map vector entry.
+ * Sets check type for a given stack map vector entry.
*/
static inline void
-vf_set_vector_check( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_check( vf_MapEntry *vector, // stack map vector
unsigned num, // vector entry number
- vf_CheckConstraint_t check ) // constraint check type
+ vf_CheckConstraint check ) // constraint check type
{
// set check for map vector entry
assert( check < VF_CHECK_NUM );
vector[num].m_ctype = check;
- return;
} // vf_set_vector_check
/**
- * Function sets constraint pool index for a given stack map vector entry.
+ * Sets constraint pool index for a given stack map vector entry.
*/
static inline void
-vf_set_vector_check_index( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_check_index( vf_MapEntry *vector, // stack map vector
unsigned num, // vector entry number
unsigned short index ) // constraint pool index
{
// set index for a map vector entry
vector[num].m_index = index;
- return;
} // vf_set_vector_check_index
/**
- * Function sets a given data type to stack map vector entry.
+ * Sets a given data type to stack map vector entry.
*/
static inline void
-vf_set_vector_type( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_type( vf_MapEntry *vector, // stack map vector
unsigned num, // vector entry number
- vf_MapType_t type ) // stack map entry type
+ vf_MapType type ) // stack map entry type
{
assert( type < SM_NUMBER );
vector[num].m_type = type;
} // vf_set_vector_type
/**
- * Function sets null data type for given stack map vector entry.
+ * Sets null data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_null( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_null( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by null
vector[num].m_type = SM_NULL;
- return;
} // vf_set_vector_stack_entry_null
/**
- * Function sets int data type for given stack map vector entry.
+ * Sets int data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_int( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_int( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by int
vector[num].m_type = SM_INT;
- return;
} // vf_set_vector_stack_entry_int
/**
- * Function sets float data type for given stack map vector entry.
+ * Sets float data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_float( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_float( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by float
vector[num].m_type = SM_FLOAT;
- return;
} // vf_set_vector_stack_entry_float
/**
- * Function sets long data type for given stack map vector entry.
+ * Sets long data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_long( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_long( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by long
vector[num].m_type = SM_LONG_HI;
vector[num + 1].m_type = SM_LONG_LO;
- return;
} // vf_set_vector_stack_entry_long
/**
- * Function sets double data type for given stack map vector entry.
+ * Sets double data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_double( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_double( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by double
vector[num].m_type = SM_DOUBLE_HI;
vector[num + 1].m_type = SM_DOUBLE_LO;
- return;
} // vf_set_vector_stack_entry_double
/**
- * Function sets return address data type for given stack map vector entry.
+ * Sets return address data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_addr( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_addr( vf_MapEntry *vector, // stack map vector
unsigned num, // vector entry number
unsigned count ) // program count
{
@@ -651,35 +624,33 @@ vf_set_vector_stack_entry_addr( vf_MapEn
} // vf_set_vector_stack_entry_addr
/**
- * Function sets single word data type for given stack map vector entry.
+ * Sets single word data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_word( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_word( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by word
vector[num].m_type = SM_WORD;
- return;
} // vf_set_vector_stack_entry_word
/**
- * Function sets double word data type for given stack map vector entry.
+ * Sets double word data type for given stack map vector entry.
*/
static inline void
-vf_set_vector_stack_entry_word2( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_stack_entry_word2( vf_MapEntry *vector, // stack map vector
unsigned num ) // vector entry number
{
// set stack map vector entry by double word
vector[num].m_type = SM_WORD2_HI;
vector[num + 1].m_type = SM_WORD2_LO;
- return;
} // vf_set_vector_stack_entry_word2
/**
- * Function sets int data type for given local variable vector entry.
+ * Sets int data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_int( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_int( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
unsigned local ) // number of local variable
{
@@ -687,14 +658,13 @@ vf_set_vector_local_var_int( vf_MapEntry
vector[num].m_type = SM_INT;
vector[num].m_is_local = true;
vector[num].m_local = ( unsigned short )local;
- return;
} // vf_set_vector_local_var_int
/**
- * Function sets float data type for given local variable vector entry.
+ * Sets float data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_float( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_float( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
unsigned local ) // number of local variable
{
@@ -702,14 +672,13 @@ vf_set_vector_local_var_float( vf_MapEnt
vector[num].m_type = SM_FLOAT;
vector[num].m_is_local = true;
vector[num].m_local = ( unsigned short )local;
- return;
} // vf_set_vector_local_var_float
/**
- * Function sets long data type for given local variable vector entry.
+ * Sets long data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_long( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_long( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
unsigned local ) // number of local variable
{
@@ -720,14 +689,13 @@ vf_set_vector_local_var_long( vf_MapEntr
vector[num + 1].m_type = SM_LONG_LO;
vector[num + 1].m_is_local = true;
vector[num + 1].m_local = ( unsigned short )( local + 1 );
- return;
} // vf_set_vector_local_var_long
/**
- * Function sets double data type for given local variable vector entry.
+ * Sets double data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_double( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_double( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
unsigned local ) // number of local variable
{
@@ -738,16 +706,15 @@ vf_set_vector_local_var_double( vf_MapEn
vector[num + 1].m_type = SM_DOUBLE_LO;
vector[num + 1].m_is_local = true;
vector[num + 1].m_local = ( unsigned short )( local + 1 );
- return;
} // vf_set_vector_local_var_double
/**
- * Function sets reference data type for given local variable vector entry.
+ * Sets reference data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_ref( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_ref( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
- vf_ValidType_t * type, // reference type
+ vf_ValidType *type, // reference type
unsigned local ) // number of local variable
{
// set stack map vector entry by reference
@@ -755,14 +722,13 @@ vf_set_vector_local_var_ref( vf_MapEntry
vector[num].m_vtype = type;
vector[num].m_is_local = true;
vector[num].m_local = ( unsigned short )local;
- return;
} // vf_set_vector_local_var_ref
/**
- * Function sets return address data type for given local variable vector entry.
+ * Sets return address data type for given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_addr( vf_MapEntry_t * vector, // stack map vector
+vf_set_vector_local_var_addr( vf_MapEntry *vector, // stack map vector
unsigned num, // vector entry number
unsigned count, // program count
unsigned local ) // number of local variable
@@ -775,19 +741,18 @@ vf_set_vector_local_var_addr( vf_MapEntr
} // vf_set_vector_local_var_addr
/**
- * Function sets a given data type for a given local variable vector entry.
+ * Sets a given data type for a given local variable vector entry.
*/
static inline void
-vf_set_vector_local_var_type( vf_MapEntry_t * vector, // local variable vector
+vf_set_vector_local_var_type( vf_MapEntry *vector, // local variable vector
unsigned num, // vector entry number
- vf_MapType_t type, // stack map entry type
+ vf_MapType type, // stack map entry type
unsigned local ) // number of local variable
{
// set stack map vector entry by reference
vector[num].m_type = type;
vector[num].m_is_local = true;
vector[num].m_local = ( unsigned short )local;
- return;
} // vf_set_vector_local_var_type
/************************************************************
@@ -798,231 +763,176 @@ vf_set_vector_local_var_type( vf_MapEntr
* Allocates memory for new code instruction in the IN stack map vector.
*/
static inline void
-vf_new_in_vector( vf_Code_t * code, // code instruction
+vf_new_in_vector( vf_Instr *instr, // code instruction
unsigned len, // vector length
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// create IN vector
- code->m_inlen = ( unsigned short )len;
- code->m_invector =
- (vf_MapEntry_t*) vf_alloc_pool_memory( pool,
- len *
- sizeof( vf_MapEntry_t ) );
- return;
+ instr->m_inlen = ( unsigned short )len;
+ instr->m_invector =
+ (vf_MapEntry*)vf_palloc( pool, len * sizeof( vf_MapEntry ) );
} // vf_new_in_vector
/**
* Sets check attribute for a code instruction in the IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_check( vf_Code_t * code, // code instruction
+vf_set_in_vector_check( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
- vf_CheckConstraint_t check ) // constraint check type
+ vf_CheckConstraint check ) // constraint check type
{
- vf_set_vector_check( code->m_invector, num, check );
- return;
+ vf_set_vector_check( instr->m_invector, num, check );
} // vf_set_in_vector_check
/**
- * Function sets constant pool index for a code instruction IN stack map vector entry.
+ * Sets constant pool index for a code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_check_index( vf_Code_t * code, // code instruction
+vf_set_in_vector_check_index( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
unsigned short index ) // constraint pool index
{
- vf_set_vector_check_index( code->m_invector, num, index );
- return;
+ vf_set_vector_check_index( instr->m_invector, num, index );
} // vf_set_in_vector_check_index
/**
- * Function sets a given data type to stack map vector entry.
+ * Sets a given data type to stack map vector entry.
*/
static inline void
-vf_set_in_vector_type( vf_Code_t * code, // code instruction
+vf_set_in_vector_type( vf_InstrHandle instr, // code instruction
unsigned num, // vector entry number
- vf_MapType_t type ) // stack map entry type
+ vf_MapType type ) // stack map entry type
{
- vf_set_vector_type( code->m_invector, num, type );
- return;
+ vf_set_vector_type( instr->m_invector, num, type );
} // vf_set_in_vector_type
/**
- * Function sets null data type for code instruction IN stack map vector entry.
- */
-static inline void UNUSED
-vf_set_in_vector_stack_entry_null( vf_Code_t * code, // code instruction
- unsigned num ) // IN vector entry number
-{
- vf_set_vector_stack_entry_null( code->m_invector, num );
- return;
-} // vf_set_in_vector_stack_entry_null
-
-/**
- * Function sets int data type for code instruction IN stack map vector entry.
+ * Sets int data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_int( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_int( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_int( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_int( instr->m_invector, num );
} // vf_set_vector_stack_entry_int
/**
- * Function sets float data type for code instruction IN stack map vector entry.
+ * Sets float data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_float( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_float( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_float( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_float( instr->m_invector, num );
} // vf_set_in_vector_stack_entry_float
/**
- * Function sets long data type for code instruction IN stack map vector entry.
+ * Sets long data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_long( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_long( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_long( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_long( instr->m_invector, num );
} // vf_set_in_vector_stack_entry_long
/**
- * Function sets double data type for code instruction IN stack map vector entry.
+ * Sets double data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_double( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_double( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_double( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_double( instr->m_invector, num );
} // vf_set_in_vector_stack_entry_double
/**
- * Function sets reference data type for code instruction IN stack map vector entry.
+ * Sets reference data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_ref( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_ref( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
- vf_ValidType_t * type ) // reference type
+ vf_ValidType *type ) // reference type
{
- vf_set_vector_stack_entry_ref( code->m_invector, num, type );
- return;
+ vf_set_vector_stack_entry_ref( instr->m_invector, num, type );
} // vf_set_in_vector_stack_entry_ref
/**
- * Function sets single word data type for code instruction IN stack map vector entry.
+ * Sets single word data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_word( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_word( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_word( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_word( instr->m_invector, num );
} // vf_set_in_vector_stack_entry_word
/**
- * Function sets double word data type for code instruction IN stack map vector entry.
+ * Sets double word data type for code instruction IN stack map vector entry.
*/
static inline void
-vf_set_in_vector_stack_entry_word2( vf_Code_t * code, // code instruction
+vf_set_in_vector_stack_entry_word2( vf_InstrHandle instr, // code instruction
unsigned num ) // IN vector entry number
{
- vf_set_vector_stack_entry_word2( code->m_invector, num );
- return;
+ vf_set_vector_stack_entry_word2( instr->m_invector, num );
} // vf_set_in_vector_stack_entry_word2
/**
- * Function sets int data type for code instruction IN local variable vector entry.
+ * Sets int data type for code instruction IN local variable vector entry.
*/
static inline void
-vf_set_in_vector_local_var_int( vf_Code_t * code, // code instruction
+vf_set_in_vector_local_var_int( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_int( code->m_invector, num, local );
- return;
+ vf_set_vector_local_var_int( instr->m_invector, num, local );
} // vf_set_in_vector_local_var_int
/**
- * Function sets float data type for code instruction IN local variable vector entry.
+ * Sets float data type for code instruction IN local variable vector entry.
*/
static inline void
-vf_set_in_vector_local_var_float( vf_Code_t * code, // code instruction
+vf_set_in_vector_local_var_float( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_float( code->m_invector, num, local );
- return;
+ vf_set_vector_local_var_float( instr->m_invector, num, local );
} // vf_set_in_vector_local_var_float
/**
- * Function sets long data type for code instruction IN local variable vector entry.
+ * Sets long data type for code instruction IN local variable vector entry.
*/
static inline void
-vf_set_in_vector_local_var_long( vf_Code_t * code, // code instruction
+vf_set_in_vector_local_var_long( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_long( code->m_invector, num, local );
- return;
+ vf_set_vector_local_var_long( instr->m_invector, num, local );
} // vf_set_in_vector_local_var_long
/**
- * Function sets double data type for code instruction IN local variable vector entry.
+ * Sets double data type for code instruction IN local variable vector entry.
*/
static inline void
-vf_set_in_vector_local_var_double( vf_Code_t * code, // code instruction
+vf_set_in_vector_local_var_double( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_double( code->m_invector, num, local );
- return;
+ vf_set_vector_local_var_double( instr->m_invector, num, local );
} // vf_set_in_vector_local_var_double
/**
- * Function sets reference data type for code instruction IN local variable vector entry.
+ * Sets reference data type for code instruction IN local variable vector entry.
*/
static inline void
-vf_set_in_vector_local_var_ref( vf_Code_t * code, // code instruction
+vf_set_in_vector_local_var_ref( vf_InstrHandle instr, // code instruction
unsigned num, // IN vector entry number
- vf_ValidType_t * type, // reference type
+ vf_ValidType *type, // reference type
unsigned local ) // local variable number
{
- vf_set_vector_local_var_ref( code->m_invector, num, type, local );
- return;
+ vf_set_vector_local_var_ref( instr->m_invector, num, type, local );
} // vf_set_in_vector_local_var_ref
-/**
- * Function sets return address data type for code instruction IN local variable vector entry.
- */
-static inline void
-vf_set_in_vector_local_var_addr( vf_Code_t * code, // code instruction
- unsigned num, // IN vector entry number
- unsigned count, // program count
- unsigned local ) // local variable number
-{
- vf_set_vector_local_var_addr( code->m_invector, num, count, local );
- return;
-} // vf_set_in_vector_local_var_addr
-
-/**
- * Function sets a given data type for code instruction IN local variable vector entry.
- */
-static inline void UNUSED
-vf_set_in_vector_local_var_type( vf_Code_t * code, // code instruction
- unsigned num, // IN vector entry number
- vf_MapType_t type, // stack map entry
- unsigned local ) // local variable number
-{
- vf_set_vector_local_var_type( code->m_invector, num, type, local );
- return;
-} // vf_set_in_vector_local_var_type
-
/************************************************************
***************** OUT Vector functions *********************
************************************************************/
@@ -1031,235 +941,157 @@ vf_set_in_vector_local_var_type( vf_Code
* Function allocates memory for new code instruction OUT stack map vector.
*/
static inline void
-vf_new_out_vector( vf_Code_t * code, // code instruction
+vf_new_out_vector( vf_Instr *instr, // code instruction
unsigned len, // vector length
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// create stack map OUT vector
- code->m_outlen = ( unsigned short )len;
- code->m_outvector =
- (vf_MapEntry_t*) vf_alloc_pool_memory( pool,
- len *
- sizeof( vf_MapEntry_t ) );
- return;
+ instr->m_outlen = ( unsigned short )len;
+ instr->m_outvector =
+ (vf_MapEntry*)vf_palloc( pool, len * sizeof( vf_MapEntry ) );
} // vf_new_out_vector
/**
- * Function sets check attribute for a code instruction OUT stack map vector entry.
- */
-static inline void UNUSED
-vf_set_out_vector_check( vf_Code_t * code, // code instruction
- unsigned num, // OUT vector entry number
- vf_CheckConstraint_t check ) // constraint check type
-{
- vf_set_vector_check( code->m_outvector, num, check );
- return;
-} // vf_set_out_vector_check
-
-/**
- * Function sets check attribute for code instruction OUT stack map vector entry.
- */
-static inline void UNUSED
-vf_set_out_vector_check_index( vf_Code_t * code, // code instruction
- unsigned num, // OUT vector entry number
- unsigned short index ) // constraint pool index
-{
- vf_set_vector_check_index( code->m_outvector, num, index );
- return;
-} // vf_set_out_vector_check_index
-
-/**
- * Function sets a given data type to stack map OUT vector entry.
+ * Sets a given data type to stack map OUT vector entry.
*/
static inline void
-vf_set_out_vector_type( vf_Code_t * code, // code instruction
+vf_set_out_vector_type( vf_InstrHandle instr, // code instruction
unsigned num, // vector entry number
- vf_MapType_t type ) // stack map entry type
+ vf_MapType type ) // stack map entry type
{
- vf_set_vector_type( code->m_outvector, num, type );
- return;
+ vf_set_vector_type( instr->m_outvector, num, type );
} // vf_set_out_vector_type
/**
- * Function sets a given program counter to stack map OUT vector entry.
+ * Sets a given program counter to stack map OUT vector entry.
*/
static inline void
-vf_set_out_vector_opcode_new( vf_Code_t * code, // code instruction
+vf_set_out_vector_opcode_new( vf_InstrHandle instr, // code instruction
unsigned num, // vector entry number
unsigned opcode_new ) // new opcode
{
- code->m_outvector[num].m_new = opcode_new;
- return;
+ instr->m_outvector[num].m_new = opcode_new;
} // vf_set_out_vector_opcode_new
/**
- * Function sets null data type for code instruction OUT stack map vector entry.
- */
-static inline void UNUSED
-vf_set_out_vector_stack_entry_null( vf_Code_t * code, // code instruction
- unsigned num ) // OUT vector entry number
-{
- vf_set_vector_stack_entry_null( code->m_outvector, num );
- return;
-} // vf_set_out_vector_stack_entry_null
-
-/**
- * Function sets int data type for code instruction OUT stack map vector entry.
+ * Sets int data type for code instruction OUT stack map vector entry.
*/
static inline void
-vf_set_out_vector_stack_entry_int( vf_Code_t * code, // code instruction
+vf_set_out_vector_stack_entry_int( vf_InstrHandle instr, // code instruction
unsigned num ) // OUT vector entry number
{
- vf_set_vector_stack_entry_int( code->m_outvector, num );
- return;
+ vf_set_vector_stack_entry_int( instr->m_outvector, num );
} // vf_set_vector_stack_entry_int
/**
- * Function sets float data type for code instruction OUT stack map vector entry.
+ * Sets float data type for code instruction OUT stack map vector entry.
*/
static inline void
-vf_set_out_vector_stack_entry_float( vf_Code_t * code, // code instruction
+vf_set_out_vector_stack_entry_float( vf_InstrHandle instr, // code instruction
unsigned num ) // OUT vector entry number
{
- vf_set_vector_stack_entry_float( code->m_outvector, num );
- return;
+ vf_set_vector_stack_entry_float( instr->m_outvector, num );
} // vf_set_out_vector_stack_entry_float
/**
- * Function sets long data type for code instruction OUT stack map vector entry.
+ * Sets long data type for code instruction OUT stack map vector entry.
*/
static inline void
-vf_set_out_vector_stack_entry_long( vf_Code_t * code, // code instruction
+vf_set_out_vector_stack_entry_long( vf_InstrHandle instr, // code instruction
unsigned num ) // OUT vector entry number
{
- vf_set_vector_stack_entry_long( code->m_outvector, num );
- return;
+ vf_set_vector_stack_entry_long( instr->m_outvector, num );
} // vf_set_out_vector_stack_entry_long
/**
- * Function sets double data type for code instruction OUT stack map vector entry.
+ * Sets double data type for code instruction OUT stack map vector entry.
*/
static inline void
-vf_set_out_vector_stack_entry_double( vf_Code_t * code, // code instruction
+vf_set_out_vector_stack_entry_double( vf_InstrHandle instr, // code instruction
unsigned num ) // OUT vector entry number
{
- vf_set_vector_stack_entry_double( code->m_outvector, num );
- return;
+ vf_set_vector_stack_entry_double( instr->m_outvector, num );
} // vf_set_out_vector_stack_entry_double
/**
- * Function sets reference data type for code instruction OUT stack map vector entry.
+ * Sets reference data type for code instruction OUT stack map vector entry.
*/
static inline void
-vf_set_out_vector_stack_entry_ref( vf_Code_t * code, // code instruction
+vf_set_out_vector_stack_entry_ref( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
- vf_ValidType_t * type ) // reference type
+ vf_ValidType *type ) // reference type
{
- vf_set_vector_stack_entry_ref( code->m_outvector, num, type );
- return;
+ vf_set_vector_stack_entry_ref( instr->m_outvector, num, type );
} // vf_set_out_vector_stack_entry_ref
/**
- * Function sets return address data type for code instruction OUT stack map vector entry.
- */
-static inline void
-vf_set_out_vector_stack_entry_addr( vf_Code_t * code, // code instruction
- unsigned num, // OUT vector entry number
- unsigned count ) // program count
-{
- vf_set_vector_stack_entry_addr( code->m_outvector, num, count );
- return;
-} // vf_set_out_vector_stack_entry_addr
-
-/**
- * Function sets int data type for code instruction OUT local variable vector entry.
+ * Sets int data type for code instruction OUT local variable vector entry.
*/
static inline void
-vf_set_out_vector_local_var_int( vf_Code_t * code, // code instruction
+vf_set_out_vector_local_var_int( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_int( code->m_outvector, num, local );
- return;
+ vf_set_vector_local_var_int( instr->m_outvector, num, local );
} // vf_set_out_vector_local_var_int
/**
- * Function sets float data type for code instruction OUT local variable vector entry.
+ * Sets float data type for code instruction OUT local variable vector entry.
*/
static inline void
-vf_set_out_vector_local_var_float( vf_Code_t * code, // code instruction
+vf_set_out_vector_local_var_float( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_float( code->m_outvector, num, local );
- return;
+ vf_set_vector_local_var_float( instr->m_outvector, num, local );
} // vf_set_out_vector_local_var_float
/**
- * Function sets long data type for code instruction OUT local variable vector entry.
+ * Sets long data type for code instruction OUT local variable vector entry.
*/
static inline void
-vf_set_out_vector_local_var_long( vf_Code_t * code, // code instruction
+vf_set_out_vector_local_var_long( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_long( code->m_outvector, num, local );
- return;
+ vf_set_vector_local_var_long( instr->m_outvector, num, local );
} // vf_set_out_vector_local_var_long
/**
- * Function sets double data type for code instruction OUT local variable vector entry.
+ * Sets double data type for code instruction OUT local variable vector entry.
*/
static inline void
-vf_set_out_vector_local_var_double( vf_Code_t * code, // code instruction
+vf_set_out_vector_local_var_double( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
unsigned local ) // local variable number
{
- vf_set_vector_local_var_double( code->m_outvector, num, local );
- return;
+ vf_set_vector_local_var_double( instr->m_outvector, num, local );
} // vf_set_out_vector_local_var_double
/**
- * Function sets reference data type for code instruction OUT local variable vector entry.
- */
-static inline void UNUSED
-vf_set_out_vector_local_var_ref( vf_Code_t * code, // code instruction
- unsigned num, // OUT vector entry number
- vf_ValidType_t * type, // reference type
- unsigned local ) // local variable number
-{
- vf_set_vector_local_var_ref( code->m_outvector, num, type, local );
- return;
-} // vf_set_out_vector_local_var_ref
-
-/**
- * Function sets a given data type for code instruction OUT local variable vector entry.
+ * Sets a given data type for code instruction OUT local variable vector entry.
*/
static inline void
-vf_set_out_vector_local_var_type( vf_Code_t * code, // code instruction
+vf_set_out_vector_local_var_type( vf_InstrHandle instr, // code instruction
unsigned num, // OUT vector entry number
- vf_MapType_t type, // stack map entry
+ vf_MapType type, // stack map entry
unsigned local ) // local variable number
{
- vf_set_vector_local_var_type( code->m_outvector, num, type, local );
- return;
-} // vf_set_in_vector_local_var_type
+ vf_set_vector_local_var_type( instr->m_outvector, num, type, local );
+} // vf_set_out_vector_local_var_type
/************************************************************
************** Parse description functions *****************
************************************************************/
/**
- * Function parses method, class or field descriptions.
+ * Parses method, class or field descriptions.
*/
void
vf_parse_description( const char *descr, // descriptor of method, class or field
- int *inlen, // returned number of IN descriptor parameters
- int *outlen ) // returned number of OUT descriptor
+ unsigned short *inlen, // returned number of IN descriptor parameters
+ unsigned short *outlen ) // returned number of OUT descriptor
// parameters (for method)
{
- int *count;
- unsigned index;
-
/**
* Check parameters
*/
@@ -1274,19 +1106,21 @@ vf_parse_description( const char *descr,
*outlen = 0;
}
bool array = false;
- for( index = 0, count = inlen; descr[index]; index++ ) {
+
+ // start parsing input parameters
+ unsigned short *count = inlen;
+ for( unsigned short index = 0; descr[index]; index++ ) {
switch ( descr[index] ) {
case 'L':
- // skip method name
+ // skip class name
do {
index++;
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
if( !descr[index] ) {
- VERIFY_DEBUG
+ VF_DIE
( "vf_parse_description: incorrect structure of constant pool" );
- vf_error();
}
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
} while( descr[index] != ';' );
case 'B':
case 'C':
@@ -1314,13 +1148,12 @@ vf_parse_description( const char *descr,
// skip array structure
do {
index++;
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
if( !descr[index] ) {
- VERIFY_DEBUG
+ VF_DIE
( "vf_parse_description: incorrect structure of constant pool" );
- vf_error();
}
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
} while( descr[index] == '[' );
index--;
( *count )++; // increase stack value
@@ -1334,25 +1167,22 @@ vf_parse_description( const char *descr,
count = outlen;
break;
default:
- LDIE( 37,
- "Verifier: vf_parse_description: incorrect structure of constant pool" );
+ VF_DIE
+ ( "vf_parse_description: incorrect structure of constant pool" );
break;
}
}
- return;
} // vf_parse_description
static inline void
vf_set_array_ref( const char *type,
unsigned len,
- vf_MapEntry_t * vector,
- unsigned *index, vf_Context_t * ctex )
+ vf_MapEntry *vector, unsigned *index, vf_ContextHandle ctx )
{
// set array reference entry
- vf_ValidType_t *valid = ctex->m_type->NewType( type, len );
+ vf_ValidType *valid = ctx->m_type->NewType( type, len );
vf_set_vector_stack_entry_ref( vector, *index, valid );
( *index )++;
- return;
} // vf_set_array_ref
/**
@@ -1360,19 +1190,19 @@ vf_set_array_ref( const char *type,
*/
void
vf_set_description_vector( const char *descr, // descriptor
- int inlen, // number of entries for IN vector
- int add, // additional number of entries
+ unsigned short inlen, // number of entries for IN vector
+ unsigned short add, // additional number of entries
// to IN data flow vector
- int outlen, // number of entries for OUT vector
- vf_MapEntry_t ** invector, // pointer to IN vector
- vf_MapEntry_t ** outvector, // pointer to OUT vector
- vf_Context_t * ctex ) // verifier context
+ unsigned short outlen, // number of entries for OUT vector
+ vf_MapEntry **invector, // pointer to IN vector
+ vf_MapEntry **outvector, // pointer to OUT vector
+ vf_ContextHandle ctx ) // verification context
{
const char *type = 0;
unsigned index, count = 0, vector_index;
- vf_MapEntry_t **vector;
- vf_ValidType_t *valid;
- vf_VerifyPool_t *pool = ctex->m_pool;
+ vf_MapEntry **vector;
+ vf_ValidType *valid;
+ vf_Pool *pool = ctx->m_pool;
/**
* Check parameters
@@ -1409,12 +1239,12 @@ vf_set_description_vector( const char *d
} while( descr[index] != ';' );
if( !array ) {
// set vector reference entry
- valid = ctex->m_type->NewType( type, index - count );
+ valid = ctx->m_type->NewType( type, index - count );
vf_set_vector_stack_entry_ref( *vector, vector_index, valid );
vector_index++;
} else {
vf_set_array_ref( type, index - count, *vector, &vector_index,
- ctex );
+ ctx );
// reset array structure
array = false;
}
@@ -1428,13 +1258,13 @@ vf_set_description_vector( const char *d
// set integer array type
unsigned iter;
unsigned len = index - count + 1;
- char *int_array = (char*)vf_alloc_pool_memory( pool, len );
+ char *int_array = (char*)vf_palloc( pool, len );
for( iter = 0; iter < len - 1; iter++ ) {
int_array[iter] = '[';
}
int_array[iter] = 'B';
vf_set_array_ref( int_array, len, *vector, &vector_index,
- ctex );
+ ctx );
// reset array structure
array = false;
}
@@ -1449,7 +1279,7 @@ vf_set_description_vector( const char *d
vector_index++;
} else {
vf_set_array_ref( type, index - count + 1, *vector,
- &vector_index, ctex );
+ &vector_index, ctx );
// reset array structure
array = false;
}
@@ -1461,7 +1291,7 @@ vf_set_description_vector( const char *d
vector_index++;
} else {
vf_set_array_ref( type, index - count + 1, *vector,
- &vector_index, ctex );
+ &vector_index, ctx );
// reset array structure
array = false;
}
@@ -1473,7 +1303,7 @@ vf_set_description_vector( const char *d
vector_index += 2;
} else {
vf_set_array_ref( type, index - count + 1, *vector,
- &vector_index, ctex );
+ &vector_index, ctx );
// reset array structure
array = false;
}
@@ -1485,7 +1315,7 @@ vf_set_description_vector( const char *d
vector_index += 2;
} else {
vf_set_array_ref( type, index - count + 1, *vector,
- &vector_index, ctex );
+ &vector_index, ctx );
// reset array structure
array = false;
}
@@ -1516,7 +1346,6 @@ vf_set_description_vector( const char *d
break;
}
}
- return;
} // vf_set_description_vector
/************************************************************
@@ -1528,14 +1357,13 @@ vf_set_description_vector( const char *d
*/
static inline const char *
vf_get_name_from_cp_nameandtype( unsigned short index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
// get name constant pool index
unsigned short name_cp_index =
- class_get_cp_name_index( ctex->m_class, index );
+ class_get_cp_name_index( ctx->m_class, index );
// get name string from NameAndType constant pool entry
- const char *name =
- class_get_cp_utf8_bytes( ctex->m_class, name_cp_index );
+ const char *name = class_get_cp_utf8_bytes( ctx->m_class, name_cp_index );
return name;
} // vf_get_name_from_cp_nameandtype
@@ -1545,14 +1373,14 @@ vf_get_name_from_cp_nameandtype( unsigne
*/
static inline const char *
vf_get_decriptor_from_cp_nameandtype( unsigned short index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
// get description constant pool index
unsigned short descr_cp_index =
- class_get_cp_descriptor_index( ctex->m_class, index );
+ class_get_cp_descriptor_index( ctx->m_class, index );
// get descriptor from NameAndType constant pool entry
const char *descr =
- class_get_cp_utf8_bytes( ctex->m_class, descr_cp_index );
+ class_get_cp_utf8_bytes( ctx->m_class, descr_cp_index );
return descr;
} // vf_get_cp_nameandtype
@@ -1564,7 +1392,7 @@ static inline const char *
vf_get_class_valid_type( const char *class_name, // class name
size_t name_len, // class name length
size_t * len, // length of created string
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
char *result;
@@ -1582,7 +1410,7 @@ vf_get_class_valid_type( const char *cla
switch ( class_name[name_len - 1] ) {
case 'Z':
// set integer array type
- result = (char*)vf_alloc_pool_memory( pool, ( *len ) + 1 );
+ result = (char*)vf_palloc( pool, ( *len ) + 1 );
memcpy( result, class_name, name_len );
result[name_len - 1] = 'B';
break;
@@ -1595,7 +1423,7 @@ vf_get_class_valid_type( const char *cla
} else {
// create class signature
*len = name_len + 1;
- result = (char*)vf_alloc_pool_memory( pool, ( *len ) + 1 );
+ result = (char*)vf_palloc( pool, ( *len ) + 1 );
result[0] = 'L';
memcpy( &result[1], class_name, name_len );
}
@@ -1605,24 +1433,24 @@ vf_get_class_valid_type( const char *cla
/**
* Function creates valid type by given class name.
*/
-vf_ValidType_t *
+vf_ValidType *
vf_create_class_valid_type( const char *class_name, // class name
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
size_t len;
- vf_ValidType_t *result;
+ vf_ValidType *result;
// get class valid type
const char *type = vf_get_class_valid_type( class_name,
strlen( class_name ),
- &len, ctex->m_pool );
+ &len, ctx->m_pool );
// create valid type
- result = ctex->m_type->NewType( type, len );
+ result = ctx->m_type->NewType( type, len );
return result;
} // vf_create_class_valid_type
/**
- * Function checks constant pool reference entry.
+ * Checks constant pool reference entry.
* Function returns result of check and
* name string, type descriptor string and class name string (if it's needed).
*/
@@ -1631,7 +1459,7 @@ vf_check_cp_ref( unsigned short index,
const char **name, // pointer to name
const char **descr, // pointer to descriptor
const char **class_name, // pointer to class name
- vf_Context_t * ctex ) // verifier context
+ vf_ContextHandle ctx ) // verification context
{
assert( name );
assert( descr );
@@ -1639,40 +1467,39 @@ vf_check_cp_ref( unsigned short index,
// get class name if it's needed
if( class_name ) {
unsigned short class_cp_index =
- class_get_cp_ref_class_index( ctex->m_class, index );
- *class_name = vf_get_cp_class_name( ctex->m_class, class_cp_index );
+ class_get_cp_ref_class_index( ctx->m_class, index );
+ *class_name = vf_get_cp_class_name( ctx->m_class, class_cp_index );
}
// get name and descriptor from NameAndType constant pool entry
unsigned short name_and_type_cp_index =
- class_get_cp_ref_name_and_type_index( ctex->m_class, index );
- *name = vf_get_name_from_cp_nameandtype( name_and_type_cp_index, ctex );
+ class_get_cp_ref_name_and_type_index( ctx->m_class, index );
+ *name = vf_get_name_from_cp_nameandtype( name_and_type_cp_index, ctx );
*descr =
- vf_get_decriptor_from_cp_nameandtype( name_and_type_cp_index, ctex );
- return;
+ vf_get_decriptor_from_cp_nameandtype( name_and_type_cp_index, ctx );
} // vf_check_cp_ref
/**
- * Function checks constant pool Methodref and InterfaceMethodref entries.
- * Function sets IN and OUT vectors for constant pool entries.
- * Function returns result of check.
+ * Checks constant pool Methodref and InterfaceMethodref entries.
+ * Sets IN and OUT vectors for constant pool entries.
+ * @return result of the check
*/
-static Verifier_Result
+static vf_Result
vf_check_cp_method( unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
+ vf_Parse * cp_parse, // entry parse result structure
bool is_interface, // interface flag
bool stack_with_ref, // stack with this reference flag
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
// get constant pool length
- unsigned short len = class_get_cp_size( ctex->m_class );
+ unsigned short len = class_get_cp_size( ctx->m_class );
// check constant pool index
- CHECK_CONST_POOL_ID( index, len, ctex );
+ CHECK_CONST_POOL_ID( index, len, ctx );
// check constant pool type
if( is_interface ) {
- CHECK_CONST_POOL_INTERFACE( ctex, index );
+ CHECK_CONST_POOL_INTERFACE( ctx, index );
} else {
- CHECK_CONST_POOL_METHOD( ctex, index );
+ CHECK_CONST_POOL_METHOD( ctx, index );
}
// get method description and name
@@ -1680,7 +1507,7 @@ vf_check_cp_method( unsigned short index
const char *descr = NULL;
const char *class_name;
vf_check_cp_ref( index, &name, &descr,
- ( stack_with_ref ? &class_name : NULL ), ctex );
+ ( stack_with_ref ? &class_name : NULL ), ctx );
// check result
assert( name );
assert( descr );
@@ -1697,43 +1524,43 @@ vf_check_cp_method( unsigned short index
1 /* ref + vector */ ,
cp_parse->method.m_outlen,
&cp_parse->method.m_invector,
- &cp_parse->method.m_outvector, ctex );
+ &cp_parse->method.m_outvector, ctx );
// set first ref
cp_parse->method.m_inlen += 1;
- vf_ValidType_t *type = vf_create_class_valid_type( class_name, ctex );
+ vf_ValidType *type = vf_create_class_valid_type( class_name, ctx );
vf_set_vector_stack_entry_ref( cp_parse->method.m_invector, 0, type );
} else {
vf_set_description_vector( descr, cp_parse->method.m_inlen,
0 /* only vector */ ,
cp_parse->method.m_outlen,
&cp_parse->method.m_invector,
- &cp_parse->method.m_outvector, ctex );
+ &cp_parse->method.m_outvector, ctx );
}
return VER_OK;
} // vf_check_cp_method
/**
- * Function checks constant pool Fieldref entry.
- * Function sets data flow vector for constant pool entry.
- * Function returns result of check.
+ * Checks constant pool Fieldref entry.
+ * Sets data flow vector for constant pool entry.
+ * @return result of the check
*/
-static Verifier_Result
+static vf_Result
vf_check_cp_field( unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
+ vf_Parse * cp_parse, // entry parse result structure
bool stack_with_ref, // stack with this reference flag
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
// check constant pool index and type
- unsigned short len = class_get_cp_size( ctex->m_class );
- CHECK_CONST_POOL_ID( index, len, ctex );
- CHECK_CONST_POOL_FIELD( ctex, index );
+ unsigned short len = class_get_cp_size( ctx->m_class );
+ CHECK_CONST_POOL_ID( index, len, ctx );
+ CHECK_CONST_POOL_FIELD( ctx, index );
// get field description and name
const char *name = NULL;
const char *descr = NULL;
const char *class_name;
vf_check_cp_ref( index, &name, &descr,
- ( stack_with_ref ? &class_name : NULL ), ctex );
+ ( stack_with_ref ? &class_name : NULL ), ctx );
// check result
assert( name );
assert( descr );
@@ -1744,39 +1571,39 @@ vf_check_cp_field( unsigned short index,
if( stack_with_ref ) {
vf_set_description_vector( descr, cp_parse->field.f_vlen,
1 /* ref + vector */ ,
- 0, &cp_parse->field.f_vector, NULL, ctex );
+ 0, &cp_parse->field.f_vector, NULL, ctx );
// set first ref
cp_parse->field.f_vlen += 1;
- vf_ValidType_t *type = vf_create_class_valid_type( class_name, ctex );
+ vf_ValidType *type = vf_create_class_valid_type( class_name, ctx );
vf_set_vector_stack_entry_ref( cp_parse->field.f_vector, 0, type );
} else {
vf_set_description_vector( descr, cp_parse->field.f_vlen,
0 /* only vector */ ,
- 0, &cp_parse->field.f_vector, NULL, ctex );
+ 0, &cp_parse->field.f_vector, NULL, ctx );
}
return VER_OK;
} // vf_check_cp_field
/**
- * Function checks constant pool Integer, Float and String entries.
- * Function sets data flow vector for constant pool entry.
- * Function returns result of check.
+ * Checks constant pool Integer, Float and String entries.
+ * Sets data flow vector for constant pool entry.
+ * @return result of the check
*/
-static inline Verifier_Result
+static inline vf_Result
vf_check_cp_single_const( unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
- vf_Context_t * ctex ) // verifier context
+ vf_Parse * cp_parse, // entry parse result structure
+ vf_Context *ctx ) // verification context
{
// check constant pool index
- unsigned short len = class_get_cp_size( ctex->m_class );
- CHECK_CONST_POOL_ID( index, len, ctex );
+ unsigned short len = class_get_cp_size( ctx->m_class );
+ CHECK_CONST_POOL_ID( index, len, ctx );
// create stack map entry
cp_parse->field.f_vlen = 1;
- vf_new_vector( &( cp_parse->field.f_vector ), 1, ctex->m_pool );
+ vf_new_vector( &( cp_parse->field.f_vector ), 1, ctx->m_pool );
// check constant pool type and set stack map entry
- vf_ValidType_t *type;
- switch ( class_get_cp_tag( ctex->m_class, index ) ) {
+ vf_ValidType *type;
+ switch ( class_get_cp_tag( ctx->m_class, index ) ) {
case _CONSTANT_Integer:
vf_set_vector_stack_entry_int( cp_parse->field.f_vector, 0 );
break;
@@ -1784,50 +1611,50 @@ vf_check_cp_single_const( unsigned short
vf_set_vector_stack_entry_float( cp_parse->field.f_vector, 0 );
break;
case _CONSTANT_String:
- type = ctex->m_type->NewType( "Ljava/lang/String", 17 );
+ type = ctx->m_type->NewType( "Ljava/lang/String", 17 );
vf_set_vector_stack_entry_ref( cp_parse->field.f_vector, 0, type );
break;
case _CONSTANT_Class:
- if( !vf_is_class_version_14( ctex ) ) {
- type = ctex->m_type->NewType( "Ljava/lang/Class", 16 );
+ if( !vf_is_class_version_14( ctx ) ) {
+ type = ctx->m_type->NewType( "Ljava/lang/Class", 16 );
vf_set_vector_stack_entry_ref( cp_parse->field.f_vector, 0,
type );
break;
}
// if class version is 1.4 verifier fails in default
default:
- VERIFY_REPORT_METHOD( ctex, "Illegal type for constant pool entry #"
- << index << ( vf_is_class_version_14( ctex )
- ?
- ": CONSTANT_Integer, CONSTANT_Float or CONSTANT_String"
- :
- ": CONSTANT_Integer, CONSTANT_Float, CONSTANT_String "
- "or CONSTANT_Class" )
- << " are expected for ldc/ldc_w instruction" );
+ VF_REPORT( ctx, "Illegal type for constant pool entry #"
+ << index << ( vf_is_class_version_14( ctx )
+ ?
+ ": CONSTANT_Integer, CONSTANT_Float or CONSTANT_String"
+ :
+ ": CONSTANT_Integer, CONSTANT_Float, CONSTANT_String "
+ "or CONSTANT_Class" )
+ << " are expected for ldc/ldc_w instruction" );
return VER_ErrorConstantPool;
}
return VER_OK;
} // vf_check_cp_single_const
/**
- * Function checks constant pool Double and Long entries.
- * Function sets data flow vector for constant pool entry.
- * Function returns result of check.
+ * Checks constant pool Double and Long entries.
+ * Sets data flow vector for constant pool entry.
+ * @return result of the check
*/
-static inline Verifier_Result
+static inline vf_Result
vf_check_cp_double_const( unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
- vf_Context_t * ctex ) // verifier context
+ vf_Parse * cp_parse, // entry parse result structure
+ vf_Context *ctx ) // verification context
{
// check constant pool index
- unsigned short len = class_get_cp_size( ctex->m_class );
- CHECK_CONST_POOL_ID( index, len, ctex );
+ unsigned short len = class_get_cp_size( ctx->m_class );
+ CHECK_CONST_POOL_ID( index, len, ctx );
// create stack map entry
cp_parse->field.f_vlen = 2;
- vf_new_vector( &( cp_parse->field.f_vector ), 2, ctex->m_pool );
+ vf_new_vector( &( cp_parse->field.f_vector ), 2, ctx->m_pool );
// check constant pool type and set stack map entry
- switch ( class_get_cp_tag( ctex->m_class, index ) ) {
+ switch ( class_get_cp_tag( ctx->m_class, index ) ) {
case _CONSTANT_Double:
vf_set_vector_stack_entry_double( cp_parse->field.f_vector, 0 );
break;
@@ -1835,39 +1662,39 @@ vf_check_cp_double_const( unsigned short
vf_set_vector_stack_entry_long( cp_parse->field.f_vector, 0 );
break;
default:
- VERIFY_REPORT_METHOD( ctex, "Illegal type in constant pool, "
- << index <<
- ": CONSTANT_Double or CONSTANT_Long are expected" );
+ VF_REPORT( ctx, "Illegal type in constant pool, "
+ << index <<
+ ": CONSTANT_Double or CONSTANT_Long are expected" );
return VER_ErrorConstantPool;
}
return VER_OK;
} // vf_check_cp_double_const
/**
- * Function checks constant pool Class entry.
- * Function sets data flow vector for constant pool entry (if it's needed).
- * Function returns result of check.
+ * Checks constant pool Class entry.
+ * Sets data flow vector for constant pool entry (if it's needed).
+ * @return result of the check
*/
-static Verifier_Result
+static vf_Result
vf_check_cp_class( unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
- vf_Context_t * ctex ) // verifier context
+ vf_Parse * cp_parse, // entry parse result structure
+ vf_Context *ctx ) // verification context
{
// check constant pool index and type
- unsigned short len = class_get_cp_size( ctex->m_class );
- CHECK_CONST_POOL_ID( index, len, ctex );
- CHECK_CONST_POOL_CLASS( ctex, index );
+ unsigned short len = class_get_cp_size( ctx->m_class );
+ CHECK_CONST_POOL_ID( index, len, ctx );
+ CHECK_CONST_POOL_CLASS( ctx, index );
if( cp_parse ) {
// create valid type
- const char *name = vf_get_cp_class_name( ctex->m_class, index );
+ const char *name = vf_get_cp_class_name( ctx->m_class, index );
// check result
assert( name );
// create valid type for class
- vf_ValidType_t *type = vf_create_class_valid_type( name, ctex );
+ vf_ValidType *type = vf_create_class_valid_type( name, ctx );
// create stack map vector
cp_parse->field.f_vlen = 1;
- vf_new_vector( &cp_parse->field.f_vector, 1, ctex->m_pool );
+ vf_new_vector( &cp_parse->field.f_vector, 1, ctx->m_pool );
vf_set_vector_stack_entry_ref( cp_parse->field.f_vector, 0, type );
}
return VER_OK;
@@ -1875,58 +1702,58 @@ vf_check_cp_class( unsigned short index,
/**
* Function parses constant pool entry for given instruction.
- * Function sets data flow vectors for current constant pool entry.
+ * Sets data flow vectors for current constant pool entry.
* Function returns parse result.
*/
-static Verifier_Result
-vf_parse_const_pool( unsigned char code, // opcode number
+static vf_Result
+vf_parse_const_pool( unsigned char instr, // opcode number
unsigned short index, // constant pool entry index
- vf_Parse_t * cp_parse, // entry parse result structure
- vf_Context_t * ctex ) // verifier context
+ vf_Parse * cp_parse, // entry parse result structure
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
+ vf_Result result;
- switch ( code ) {
+ switch ( instr ) {
case OPCODE_INVOKEVIRTUAL:
- result = vf_check_cp_method( index, cp_parse, false, true, ctex );
+ result = vf_check_cp_method( index, cp_parse, false, true, ctx );
break;
case OPCODE_INVOKESPECIAL:
- result = vf_check_cp_method( index, cp_parse, false, true, ctex );
+ result = vf_check_cp_method( index, cp_parse, false, true, ctx );
break;
case OPCODE_INVOKESTATIC:
- result = vf_check_cp_method( index, cp_parse, false, false, ctex );
+ result = vf_check_cp_method( index, cp_parse, false, false, ctx );
break;
case OPCODE_INVOKEINTERFACE:
- result = vf_check_cp_method( index, cp_parse, true, true, ctex );
+ result = vf_check_cp_method( index, cp_parse, true, true, ctx );
break;
case OPCODE_GETSTATIC:
case OPCODE_PUTSTATIC:
- result = vf_check_cp_field( index, cp_parse, false, ctex );
+ result = vf_check_cp_field( index, cp_parse, false, ctx );
break;
case OPCODE_GETFIELD:
case OPCODE_PUTFIELD:
- result = vf_check_cp_field( index, cp_parse, true, ctex );
+ result = vf_check_cp_field( index, cp_parse, true, ctx );
break;
case OPCODE_LDC:
case OPCODE_LDC_W:
- result = vf_check_cp_single_const( index, cp_parse, ctex );
+ result = vf_check_cp_single_const( index, cp_parse, ctx );
break;
case OPCODE_LDC2_W:
- result = vf_check_cp_double_const( index, cp_parse, ctex );
+ result = vf_check_cp_double_const( index, cp_parse, ctx );
break;
case OPCODE_NEW:
- result = vf_check_cp_class( index, cp_parse, ctex );
+ result = vf_check_cp_class( index, cp_parse, ctx );
break;
case OPCODE_ANEWARRAY:
case OPCODE_CHECKCAST:
- result = vf_check_cp_class( index, cp_parse, ctex );
+ result = vf_check_cp_class( index, cp_parse, ctx );
break;
case OPCODE_INSTANCEOF:
case OPCODE_MULTIANEWARRAY:
- result = vf_check_cp_class( index, NULL, ctex );
+ result = vf_check_cp_class( index, NULL, ctx );
break;
default:
- VERIFY_DEBUG
+ VF_DEBUG
( "vf_parse_const_pool: incorrect parse of code instruction" );
return VER_ErrorInternal;
}
@@ -1938,1903 +1765,1841 @@ vf_parse_const_pool( unsigned char code,
************************************************************/
/**
- * Function sets code instruction structure for opcode null.
+ * Sets instruction structure for opcode aconst_null.
*/
static inline void
-vf_opcode_aconst_null( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_aconst_null( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
- vf_set_stack_modifier( code, 1 );
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_ref( code, 0, NULL );
- return;
+ vf_set_stack_modifier( instr, 1 );
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_ref( instr, 0, NULL );
} // vf_opcode_aconst_null
/**
- * Function sets code instruction structure for opcode iconst_n.
+ * Sets instruction structure for opcode iconst_n.
*/
static inline void
-vf_opcode_iconst_n( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_iconst_n( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
- vf_set_stack_modifier( code, 1 );
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_set_stack_modifier( instr, 1 );
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_iconst_n
/**
- * Function sets code instruction structure for opcode lconst_n.
+ * Sets instruction structure for opcode lconst_n.
*/
static inline void
-vf_opcode_lconst_n( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_lconst_n( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
- vf_set_stack_modifier( code, 2 );
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_set_stack_modifier( instr, 2 );
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_lconst_n
/**
- * Function sets code instruction structure for opcode fconst_n.
+ * Sets instruction structure for opcode fconst_n.
*/
static inline void
-vf_opcode_fconst_n( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_fconst_n( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
- vf_set_stack_modifier( code, 1 );
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_set_stack_modifier( instr, 1 );
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_fconst_n
/**
- * Function sets code instruction structure for opcode dconst_n.
+ * Sets instruction structure for opcode dconst_n.
*/
static inline void
-vf_opcode_dconst_n( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dconst_n( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
- vf_set_stack_modifier( code, 2 );
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_set_stack_modifier( instr, 2 );
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_dconst_n
/**
- * Function sets code instruction structure for opcodes ldcx.
+ * Sets instruction structure for opcodes ldcx.
*/
-static inline Verifier_Result
-vf_opcode_ldcx( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_ldcx( vf_Instr *instr, // code instruction
int modifier, // instruction stack modifier
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
result =
- vf_parse_const_pool( *( code->m_addr ), cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ vf_parse_const_pool( *( instr->m_addr ), cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code, modifier );
+ vf_set_stack_modifier( instr, modifier );
// set stack out vector
- code->m_outvector = cp_parse.field.f_vector;
- code->m_outlen = ( unsigned short )cp_parse.field.f_vlen;
+ instr->m_outvector = cp_parse.field.f_vector;
+ instr->m_outlen = ( unsigned short )cp_parse.field.f_vlen;
return VER_OK;
} // vf_opcode_ldcx
/**
- * Function sets code instruction structure for opcodes iloadx.
+ * Sets instruction structure for opcodes iloadx.
*/
static inline void
-vf_opcode_iloadx( vf_Code_t * code, // code instruction
+vf_opcode_iloadx( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_local_var_int( code, 0, local );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_local_var_int( instr, 0, local );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_iloadx
/**
- * Function sets code instruction structure for opcodes lloadx.
+ * Sets instruction structure for opcodes lloadx.
*/
static inline void
-vf_opcode_lloadx( vf_Code_t * code, // code instruction
+vf_opcode_lloadx( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 2 );
+ vf_set_stack_modifier( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_local_var_long( code, 0, local );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_local_var_long( instr, 0, local );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_lloadx
/**
- * Function sets code instruction structure for opcodes floadx.
+ * Sets instruction structure for opcodes floadx.
*/
static inline void
-vf_opcode_floadx( vf_Code_t * code, // code instruction
+vf_opcode_floadx( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_local_var_float( code, 0, local );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_local_var_float( instr, 0, local );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_floadx
/**
- * Function sets code instruction structure for opcodes dloadx.
+ * Sets instruction structure for opcodes dloadx.
*/
static inline void
-vf_opcode_dloadx( vf_Code_t * code, // code instruction
+vf_opcode_dloadx( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 2 );
+ vf_set_stack_modifier( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_local_var_double( code, 0, local );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_local_var_double( instr, 0, local );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_dloadx
/**
- * Function sets code instruction structure for opcodes aloadx.
+ * Sets instruction structure for opcodes aloadx.
*/
static inline void
-vf_opcode_aloadx( vf_Code_t * code, // code instruction
+vf_opcode_aloadx( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_local_var_ref( code, 0, NULL, local );
- vf_set_vector_check( code->m_invector, 0, VF_CHECK_UNINITIALIZED_THIS );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_local_var_ref( instr, 0, NULL, local );
+ vf_set_vector_check( instr->m_invector, 0, VF_CHECK_UNINITIALIZED_THIS );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_0 );
} // vf_opcode_aloadx
/**
- * Function sets code instruction structure for opcode iaload.
+ * Sets instruction structure for opcode iaload.
*/
static inline void
-vf_opcode_iaload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_iaload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[I", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[I", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_iaload
/**
- * Function sets code instruction structure for opcode baload.
+ * Sets instruction structure for opcode baload.
*/
static inline void
-vf_opcode_baload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_baload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[B", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[B", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_baload
/**
- * Function sets code instruction structure for opcode caload.
+ * Sets instruction structure for opcode caload.
*/
static inline void
-vf_opcode_caload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_caload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[C", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[C", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_caload
/**
- * Function sets code instruction structure for opcode saload.
+ * Sets instruction structure for opcode saload.
*/
static inline void
-vf_opcode_saload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_saload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[S", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[S", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_saload
/**
- * Function sets code instruction structure for opcode laload.
+ * Sets instruction structure for opcode laload.
*/
static inline void
-vf_opcode_laload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_laload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[J", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[J", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 2, ctex->m_pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, ctx->m_pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_laload
/**
- * Function sets code instruction structure for opcode faload.
+ * Sets instruction structure for opcode faload.
*/
static inline void
-vf_opcode_faload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_faload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[F", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[F", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_faload
/**
- * Function sets code instruction structure for opcode daload.
+ * Sets instruction structure for opcode daload.
*/
static inline void
-vf_opcode_daload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_daload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[D", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_ValidType *type = ctx->m_type->NewType( "[D", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
// create out vector
- vf_new_out_vector( code, 2, ctex->m_pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, ctx->m_pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_daload
/**
- * Function sets code instruction structure for opcode aaload.
+ * Sets instruction structure for opcode aaload.
*/
static inline void
-vf_opcode_aaload( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_aaload( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, ctex->m_pool );
+ vf_new_in_vector( instr, 2, ctx->m_pool );
// create type
- vf_set_in_vector_stack_entry_ref( code, 0, NULL );
- vf_set_in_vector_check( code, 0, VF_CHECK_REF_ARRAY );
- vf_set_in_vector_stack_entry_int( code, 1 );
- // create out vector
- vf_new_out_vector( code, 1, ctex->m_pool );
- vf_set_out_vector_type( code, 0, SM_UP_ARRAY );
- return;
+ vf_set_in_vector_stack_entry_ref( instr, 0, NULL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_REF_ARRAY );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ // create out vector
+ vf_new_out_vector( instr, 1, ctx->m_pool );
+ vf_set_out_vector_type( instr, 0, SM_UP_ARRAY );
} // vf_opcode_aaload
/**
- * Function sets code instruction structure for opcodes istorex.
+ * Sets instruction structure for opcodes istorex.
*/
static inline void
-vf_opcode_istorex( vf_Code_t * code, // code instruction
+vf_opcode_istorex( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_local_var_int( code, 0, local );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_local_var_int( instr, 0, local );
} // vf_opcode_istorex
/**
- * Function sets code instruction structure for opcodes lstorex.
+ * Sets instruction structure for opcodes lstorex.
*/
static inline void
-vf_opcode_lstorex( vf_Code_t * code, // code instruction
+vf_opcode_lstorex( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_local_var_long( code, 0, local );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_local_var_long( instr, 0, local );
} // vf_opcode_lstorex
/**
- * Function sets code instruction structure for opcodes fstorex.
+ * Sets instruction structure for opcodes fstorex.
*/
static inline void
-vf_opcode_fstorex( vf_Code_t * code, // code instruction
+vf_opcode_fstorex( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_local_var_float( code, 0, local );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_local_var_float( instr, 0, local );
} // vf_opcode_fstorex
/**
- * Function sets code instruction structure for opcodes dstorex.
+ * Sets instruction structure for opcodes dstorex.
*/
static inline void
-vf_opcode_dstorex( vf_Code_t * code, // code instruction
+vf_opcode_dstorex( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_local_var_double( code, 0, local );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_local_var_double( instr, 0, local );
} // vf_opcode_dstorex
/**
- * Function sets code instruction structure for opcodes astorex.
+ * Sets instruction structure for opcodes astorex.
*/
static inline void
-vf_opcode_astorex( vf_Code_t * code, // code instruction
+vf_opcode_astorex( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_ref( code, 0, NULL );
- vf_set_vector_check( code->m_invector, 0, VF_CHECK_UNINITIALIZED_THIS );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_ref( instr, 0, NULL );
+ vf_set_vector_check( instr->m_invector, 0, VF_CHECK_UNINITIALIZED_THIS );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_local_var_type( code, 0, SM_COPY_0, local );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_local_var_type( instr, 0, SM_COPY_0, local );
} // vf_opcode_astorex
/**
- * Function sets code instruction structure for opcode iastore.
+ * Sets instruction structure for opcode iastore.
*/
static inline void
-vf_opcode_iastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_iastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[I", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_int( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[I", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_int( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_iastore
/**
- * Function sets code instruction structure for opcode bastore.
+ * Sets instruction structure for opcode bastore.
*/
static inline void
-vf_opcode_bastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_bastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[B", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_int( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[B", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_int( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_bastore
/**
- * Function sets code instruction structure for opcode castore.
+ * Sets instruction structure for opcode castore.
*/
static inline void
-vf_opcode_castore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_castore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[C", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_int( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[C", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_int( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_castore
/**
- * Function sets code instruction structure for opcode sastore.
+ * Sets instruction structure for opcode sastore.
*/
static inline void
-vf_opcode_sastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_sastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[S", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_int( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[S", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_int( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_sastore
/**
- * Function sets code instruction structure for opcode lastore.
+ * Sets instruction structure for opcode lastore.
*/
static inline void
-vf_opcode_lastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_lastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -4 );
+ vf_set_stack_modifier( instr, -4 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, ctex->m_pool );
+ vf_new_in_vector( instr, 4, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[J", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_long( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[J", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_long( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_lastore
/**
- * Function sets code instruction structure for opcode fastore.
+ * Sets instruction structure for opcode fastore.
*/
static inline void
-vf_opcode_fastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_fastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[F", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_float( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[F", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_float( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_fastore
/**
- * Function sets code instruction structure for opcode dastore.
+ * Sets instruction structure for opcode dastore.
*/
static inline void
-vf_opcode_dastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_dastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -4 );
+ vf_set_stack_modifier( instr, -4 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, ctex->m_pool );
+ vf_new_in_vector( instr, 4, ctx->m_pool );
// create type
- vf_ValidType_t *type = ctex->m_type->NewType( "[D", 2 );
- vf_set_in_vector_stack_entry_ref( code, 0, type );
- vf_set_in_vector_stack_entry_int( code, 1 );
- vf_set_in_vector_stack_entry_double( code, 2 );
+ vf_ValidType *type = ctx->m_type->NewType( "[D", 2 );
+ vf_set_in_vector_stack_entry_ref( instr, 0, type );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ vf_set_in_vector_stack_entry_double( instr, 2 );
// set check
- vf_set_in_vector_check( code, 0, VF_CHECK_EQUAL );
- return;
+ vf_set_in_vector_check( instr, 0, VF_CHECK_EQUAL );
} // vf_opcode_dastore
/**
- * Function sets code instruction structure for opcode aastore.
+ * Sets instruction structure for opcode aastore.
*/
static inline void
-vf_opcode_aastore( vf_Code_t * code, // code instruction
- vf_Context_t * ctex ) // verifier context
+vf_opcode_aastore( vf_Instr *instr, // code instruction
+ vf_ContextHandle ctx ) // verification context
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, ctex->m_pool );
+ vf_new_in_vector( instr, 3, ctx->m_pool );
// create type
- vf_set_in_vector_stack_entry_ref( code, 0, NULL );
- vf_set_in_vector_check( code, 0, VF_CHECK_REF_ARRAY );
- vf_set_in_vector_stack_entry_int( code, 1 );
- if( vf_is_class_version_14( ctex ) ) {
- vf_set_in_vector_type( code, 2, SM_UP_ARRAY );
+ vf_set_in_vector_stack_entry_ref( instr, 0, NULL );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_REF_ARRAY );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
+ if( vf_is_class_version_14( ctx ) ) {
+ vf_set_in_vector_type( instr, 2, SM_UP_ARRAY );
} else {
- vf_set_in_vector_stack_entry_ref( code, 2, NULL );
+ vf_set_in_vector_stack_entry_ref( instr, 2, NULL );
}
- return;
} // vf_opcode_aastore
/**
- * Function sets code instruction structure for opcode pop.
+ * Sets instruction structure for opcode pop.
*/
static inline void
-vf_opcode_pop( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_pop( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_word( code, 0 );
- return;
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_word( instr, 0 );
} // vf_opcode_pop
/**
- * Function sets code instruction structure for opcode pop2.
+ * Sets instruction structure for opcode pop2.
*/
static inline void
-vf_opcode_pop2( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_pop2( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_word2( code, 0 );
- return;
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_word2( instr, 0 );
} // vf_opcode_pop2
/**
- * Function sets code instruction structure for opcode dup.
+ * Sets instruction structure for opcode dup.
*/
static inline void
-vf_opcode_dup( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_word( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_word( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_0 );
- vf_set_out_vector_type( code, 1, SM_COPY_0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_0 );
} // vf_opcode_dup
/**
- * Function sets code instruction structure for opcode dup_x1.
+ * Sets instruction structure for opcode dup_x1.
*/
static inline void
-vf_opcode_dup_x1( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup_x1( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_word( code, 0 );
- vf_set_in_vector_stack_entry_word( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_word( instr, 0 );
+ vf_set_in_vector_stack_entry_word( instr, 1 );
// create out vector
- vf_new_out_vector( code, 3, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_1 );
- vf_set_out_vector_type( code, 1, SM_COPY_0 );
- vf_set_out_vector_type( code, 2, SM_COPY_1 );
- return;
+ vf_new_out_vector( instr, 3, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 2, SM_COPY_1 );
} // vf_opcode_dup_x1
/**
- * Function sets code instruction structure for opcode dup_x2.
+ * Sets instruction structure for opcode dup_x2.
*/
static inline void
-vf_opcode_dup_x2( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup_x2( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, pool );
- vf_set_in_vector_stack_entry_word2( code, 0 );
- vf_set_in_vector_stack_entry_word( code, 2 );
+ vf_new_in_vector( instr, 3, pool );
+ vf_set_in_vector_stack_entry_word2( instr, 0 );
+ vf_set_in_vector_stack_entry_word( instr, 2 );
// create out vector
- vf_new_out_vector( code, 4, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_2 );
- vf_set_out_vector_type( code, 1, SM_COPY_0 );
- vf_set_out_vector_type( code, 2, SM_COPY_1 );
- vf_set_out_vector_type( code, 3, SM_COPY_2 );
- return;
+ vf_new_out_vector( instr, 4, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_2 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 2, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 3, SM_COPY_2 );
} // vf_opcode_dup_x2
/**
- * Function sets code instruction structure for opcode dup2.
+ * Sets instruction structure for opcode dup2.
*/
static inline void
-vf_opcode_dup2( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup2( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 2 );
+ vf_set_stack_modifier( instr, 2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_word2( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_word2( instr, 0 );
// create out vector
- vf_new_out_vector( code, 4, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_0 );
- vf_set_out_vector_type( code, 1, SM_COPY_1 );
- vf_set_out_vector_type( code, 2, SM_COPY_0 );
- vf_set_out_vector_type( code, 3, SM_COPY_1 );
- return;
+ vf_new_out_vector( instr, 4, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 2, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 3, SM_COPY_1 );
} // vf_opcode_dup2
/**
- * Function sets code instruction structure for opcode dup2_x1.
+ * Sets instruction structure for opcode dup2_x1.
*/
static inline void
-vf_opcode_dup2_x1( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup2_x1( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 2 );
+ vf_set_stack_modifier( instr, 2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, pool );
- vf_set_in_vector_stack_entry_word( code, 0 );
- vf_set_in_vector_stack_entry_word2( code, 1 );
+ vf_new_in_vector( instr, 3, pool );
+ vf_set_in_vector_stack_entry_word( instr, 0 );
+ vf_set_in_vector_stack_entry_word2( instr, 1 );
// create out vector
- vf_new_out_vector( code, 5, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_1 );
- vf_set_out_vector_type( code, 1, SM_COPY_2 );
- vf_set_out_vector_type( code, 2, SM_COPY_0 );
- vf_set_out_vector_type( code, 3, SM_COPY_1 );
- vf_set_out_vector_type( code, 4, SM_COPY_2 );
- return;
+ vf_new_out_vector( instr, 5, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_2 );
+ vf_set_out_vector_type( instr, 2, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 3, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 4, SM_COPY_2 );
} // vf_opcode_dup2_x1
/**
- * Function sets code instruction structure for opcode dup2_x2.
+ * Sets instruction structure for opcode dup2_x2.
*/
static inline void
-vf_opcode_dup2_x2( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dup2_x2( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 2 );
+ vf_set_stack_modifier( instr, 2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_word2( code, 0 );
- vf_set_in_vector_stack_entry_word2( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_word2( instr, 0 );
+ vf_set_in_vector_stack_entry_word2( instr, 2 );
// create out vector
- vf_new_out_vector( code, 6, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_2 );
- vf_set_out_vector_type( code, 1, SM_COPY_3 );
- vf_set_out_vector_type( code, 2, SM_COPY_0 );
- vf_set_out_vector_type( code, 3, SM_COPY_1 );
- vf_set_out_vector_type( code, 4, SM_COPY_2 );
- vf_set_out_vector_type( code, 5, SM_COPY_3 );
- return;
+ vf_new_out_vector( instr, 6, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_2 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_3 );
+ vf_set_out_vector_type( instr, 2, SM_COPY_0 );
+ vf_set_out_vector_type( instr, 3, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 4, SM_COPY_2 );
+ vf_set_out_vector_type( instr, 5, SM_COPY_3 );
} // vf_opcode_dup2_x2
/**
- * Function sets code instruction structure for opcode swap.
+ * Sets instruction structure for opcode swap.
*/
static inline void
-vf_opcode_swap( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_swap( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_word( code, 0 );
- vf_set_in_vector_stack_entry_word( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_word( instr, 0 );
+ vf_set_in_vector_stack_entry_word( instr, 1 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_type( code, 0, SM_COPY_1 );
- vf_set_out_vector_type( code, 1, SM_COPY_0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_type( instr, 0, SM_COPY_1 );
+ vf_set_out_vector_type( instr, 1, SM_COPY_0 );
} // vf_opcode_swap
/**
- * Function sets code instruction structure for opcode iadd.
+ * Sets instruction structure for opcode iadd.
*/
static inline void
-vf_opcode_iadd( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_iadd( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_iadd
/**
- * Function sets code instruction structure for opcode ladd.
+ * Sets instruction structure for opcode ladd.
*/
static inline void
-vf_opcode_ladd( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_ladd( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
- vf_set_in_vector_stack_entry_long( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
+ vf_set_in_vector_stack_entry_long( instr, 2 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_ladd
/**
- * Function sets code instruction structure for opcode fadd.
+ * Sets instruction structure for opcode fadd.
*/
static inline void
-vf_opcode_fadd( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_fadd( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
- vf_set_in_vector_stack_entry_float( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
+ vf_set_in_vector_stack_entry_float( instr, 1 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_fadd
/**
- * Function sets code instruction structure for opcode dadd.
+ * Sets instruction structure for opcode dadd.
*/
static inline void
-vf_opcode_dadd( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dadd( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
- vf_set_in_vector_stack_entry_double( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
+ vf_set_in_vector_stack_entry_double( instr, 2 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_dadd
/**
- * Function sets code instruction structure for opcode ineg.
+ * Sets instruction structure for opcode ineg.
*/
static inline void
-vf_opcode_ineg( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_ineg( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_ineg
/**
- * Function sets code instruction structure for opcode lneg.
+ * Sets instruction structure for opcode lneg.
*/
static inline void
-vf_opcode_lneg( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_lneg( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_lneg
/**
- * Function sets code instruction structure for opcode fneg.
+ * Sets instruction structure for opcode fneg.
*/
static inline void
-vf_opcode_fneg( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_fneg( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_fneg
/**
- * Function sets code instruction structure for opcode dneg.
+ * Sets instruction structure for opcode dneg.
*/
static inline void
-vf_opcode_dneg( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dneg( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_dneg
/**
- * Function sets code instruction structure for bit operation opcodes.
+ * Sets instruction structure for bit operation opcodes.
*/
static inline void
-vf_opcode_ibit( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_ibit( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- vf_set_in_vector_stack_entry_int( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_ibit
/**
- * Function sets code instruction structure for opcodes lshx.
+ * Sets instruction structure for opcodes lshx.
*/
static inline void
-vf_opcode_lshx( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_lshx( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 3 );
+ vf_set_min_stack( instr, 3 );
// create in vector
- vf_new_in_vector( code, 3, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
- vf_set_in_vector_stack_entry_int( code, 2 );
+ vf_new_in_vector( instr, 3, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
+ vf_set_in_vector_stack_entry_int( instr, 2 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_lshx
/**
- * Function sets code instruction structure for opcode land.
+ * Sets instruction structure for opcode land.
*/
static inline void
-vf_opcode_land( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_land( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
- vf_set_in_vector_stack_entry_long( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
+ vf_set_in_vector_stack_entry_long( instr, 2 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_land
/**
- * Function sets code instruction structure for opcode iinc.
+ * Sets instruction structure for opcode iinc.
*/
static inline void
-vf_opcode_iinc( vf_Code_t * code, // code instruction
+vf_opcode_iinc( vf_Instr *instr, // code instruction
unsigned local, // local variable number
- vf_VerifyPool_t * pool ) // memory pool
+ vf_Pool *pool ) // memory pool
{
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_local_var_int( code, 0, local );
- return;
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_local_var_int( instr, 0, local );
} // vf_opcode_iinc
/**
- * Function sets code instruction structure for opcode i2l.
+ * Sets instruction structure for opcode i2l.
*/
static inline void
-vf_opcode_i2l( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_i2l( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_i2l
/**
- * Function sets code instruction structure for opcode i2f.
+ * Sets instruction structure for opcode i2f.
*/
static inline void
-vf_opcode_i2f( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_i2f( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_i2f
/**
- * Function sets code instruction structure for opcode i2d.
+ * Sets instruction structure for opcode i2d.
*/
static inline void
-vf_opcode_i2d( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_i2d( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_i2d
/**
- * Function sets code instruction structure for opcode l2i.
+ * Sets instruction structure for opcode l2i.
*/
static inline void
-vf_opcode_l2i( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_l2i( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_l2i
/**
- * Function sets code instruction structure for opcode l2f.
+ * Sets instruction structure for opcode l2f.
*/
static inline void
-vf_opcode_l2f( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_l2f( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_l2f
/**
- * Function sets code instruction structure for opcode l2d.
+ * Sets instruction structure for opcode l2d.
*/
static inline void
-vf_opcode_l2d( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_l2d( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_l2d
/**
- * Function sets code instruction structure for opcode f2i.
+ * Sets instruction structure for opcode f2i.
*/
static inline void
-vf_opcode_f2i( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_f2i( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_f2i
/**
- * Function sets code instruction structure for opcode f2l.
+ * Sets instruction structure for opcode f2l.
*/
static inline void
-vf_opcode_f2l( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_f2l( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_f2l
/**
- * Function sets code instruction structure for opcode f2d.
+ * Sets instruction structure for opcode f2d.
*/
static inline void
-vf_opcode_f2d( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_f2d( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, 1 );
+ vf_set_stack_modifier( instr, 1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_double( instr, 0 );
} // vf_opcode_f2d
/**
- * Function sets code instruction structure for opcode d2i.
+ * Sets instruction structure for opcode d2i.
*/
static inline void
-vf_opcode_d2i( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_d2i( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_d2i
/**
- * Function sets code instruction structure for opcode d2l.
+ * Sets instruction structure for opcode d2l.
*/
static inline void
-vf_opcode_d2l( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_d2l( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
// create out vector
- vf_new_out_vector( code, 2, pool );
- vf_set_out_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_out_vector( instr, 2, pool );
+ vf_set_out_vector_stack_entry_long( instr, 0 );
} // vf_opcode_d2l
/**
- * Function sets code instruction structure for opcode d2f.
+ * Sets instruction structure for opcode d2f.
*/
static inline void
-vf_opcode_d2f( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_d2f( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_float( instr, 0 );
} // vf_opcode_d2f
/**
- * Function sets code instruction structure for opcode i2b.
+ * Sets instruction structure for opcode i2b.
*/
static inline void
-vf_opcode_i2b( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_i2b( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_i2b
/**
- * Function sets code instruction structure for opcode lcmp.
+ * Sets instruction structure for opcode lcmp.
*/
static inline void
-vf_opcode_lcmp( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_lcmp( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
- vf_set_in_vector_stack_entry_long( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
+ vf_set_in_vector_stack_entry_long( instr, 2 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_lcmp
/**
- * Function sets code instruction structure for opcodes fcmpx.
+ * Sets instruction structure for opcodes fcmpx.
*/
static inline void
-vf_opcode_fcmpx( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_fcmpx( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
- vf_set_in_vector_stack_entry_float( code, 1 );
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
+ vf_set_in_vector_stack_entry_float( instr, 1 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_fcmpx
/**
- * Function sets code instruction structure for opcodes dcmpx.
+ * Sets instruction structure for opcodes dcmpx.
*/
static inline void
-vf_opcode_dcmpx( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dcmpx( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -3 );
+ vf_set_stack_modifier( instr, -3 );
// set minimal stack for instruction
- vf_set_min_stack( code, 4 );
+ vf_set_min_stack( instr, 4 );
// create in vector
- vf_new_in_vector( code, 4, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
- vf_set_in_vector_stack_entry_double( code, 2 );
+ vf_new_in_vector( instr, 4, pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
+ vf_set_in_vector_stack_entry_double( instr, 2 );
// create out vector
- vf_new_out_vector( code, 1, pool );
- vf_set_out_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_out_vector( instr, 1, pool );
+ vf_set_out_vector_stack_entry_int( instr, 0 );
} // vf_opcode_dcmpx
/**
- * Function sets code instruction structure for opcode ifeq.
+ * Sets instruction structure for opcode ifeq.
*/
static inline void
-vf_opcode_ifeq( vf_Code_t * code, // code instruction
- vf_BCode_t * icode1, // first branch instruction
- vf_BCode_t * icode2, // second branch instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_ifeq( vf_Instr *instr, // code instruction
+ vf_BCode *icode1, // first branch instruction
+ vf_BCode *icode2, // second branch instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode1 );
+ icode1->m_is_bb_start = true;
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode2 );
+ icode2->m_is_bb_start = true;
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
} // vf_opcode_ifeq
/**
- * Function sets code instruction structure for opcode if_icmpeq.
+ * Sets instruction structure for opcode if_icmpeq.
*/
static inline void
-vf_opcode_if_icmpeq( vf_Code_t * code, // code instruction
- vf_BCode_t * icode1, // first branch instruction
- vf_BCode_t * icode2, // second branch instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_if_icmpeq( vf_Instr *instr, // code instruction
+ vf_BCode *icode1, // first branch instruction
+ vf_BCode *icode2, // second branch instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode1 );
+ icode1->m_is_bb_start = true;
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode2 );
+ icode2->m_is_bb_start = true;
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- vf_set_in_vector_stack_entry_int( code, 1 );
- return;
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
+ vf_set_in_vector_stack_entry_int( instr, 1 );
} // vf_opcode_if_icmpeq
/**
- * Function sets code instruction structure for opcode if_acmpeq.
+ * Sets instruction structure for opcode if_acmpeq.
*/
static inline void
-vf_opcode_if_acmpeq( vf_Code_t * code, // code instruction
- vf_BCode_t * icode1, // first branch instruction
- vf_BCode_t * icode2, // second branch instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_if_acmpeq( vf_Instr *instr, // code instruction
+ vf_BCode *icode1, // first branch instruction
+ vf_BCode *icode2, // second branch instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -2 );
+ vf_set_stack_modifier( instr, -2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode1 );
+ icode1->m_is_bb_start = true;
// set begin of basic block for branch instruction
- vf_set_basic_block_flag( icode2 );
+ icode2->m_is_bb_start = true;
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_ref( code, 0, NULL );
- vf_set_in_vector_stack_entry_ref( code, 1, NULL );
- return;
+ vf_new_in_vector( instr, 2, pool );
+ vf_set_in_vector_stack_entry_ref( instr, 0, NULL );
+ vf_set_in_vector_stack_entry_ref( instr, 1, NULL );
} // vf_opcode_if_acmpeq
/**
- * Function sets code instruction structure for opcode switch.
+ * Sets instruction structure for opcode switch.
*/
static inline void
-vf_opcode_switch( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_switch( vf_Instr *instr, // code instruction
+ vf_Pool *pool ) // memory pool
{
// set stack modifier for instruction
- vf_set_stack_modifier( code, -1 );
+ vf_set_stack_modifier( instr, -1 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_in_vector( instr, 1, pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
} // vf_opcode_switch
/**
- * Function sets code instruction structure for opcode ireturn.
+ * Sets in vectors for return instruction.
*/
static inline void
-vf_opcode_ireturn( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_return( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
{
// set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
+ vf_set_instr_type( instr, VF_INSTR_RETURN );
+ // create and set edge branch to exit
+ vf_set_basic_block_flag( next_pc, ctx );
+} // vf_opcode_return
+
+/**
+ * Sets instruction structure for opcode ireturn.
+ */
+static inline void
+vf_opcode_ireturn( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
+{
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_int( code, 0 );
- return;
+ vf_new_in_vector( instr, 1, ctx->m_pool );
+ vf_set_in_vector_stack_entry_int( instr, 0 );
+ // set flag and make checks
+ vf_opcode_return( instr, next_pc, ctx );
} // vf_opcode_ireturn
/**
- * Function sets code instruction structure for opcode lreturn.
+ * Sets instruction structure for opcode lreturn.
*/
static inline void
-vf_opcode_lreturn( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_lreturn( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
{
- // set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_long( code, 0 );
- return;
+ vf_new_in_vector( instr, 2, ctx->m_pool );
+ vf_set_in_vector_stack_entry_long( instr, 0 );
+ // set flag and make checks
+ vf_opcode_return( instr, next_pc, ctx );
} // vf_opcode_lreturn
/**
- * Function sets code instruction structure for opcode freturn.
+ * Sets instruction structure for opcode freturn.
*/
static inline void
-vf_opcode_freturn( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_freturn( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
{
- // set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_float( code, 0 );
- return;
+ vf_new_in_vector( instr, 1, ctx->m_pool );
+ vf_set_in_vector_stack_entry_float( instr, 0 );
+ // set flag and make checks
+ vf_opcode_return( instr, next_pc, ctx );
} // vf_opcode_freturn
/**
- * Function sets code instruction structure for opcode dreturn.
+ * Sets instruction structure for opcode dreturn.
*/
static inline void
-vf_opcode_dreturn( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_dreturn( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
{
- // set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
// set minimal stack for instruction
- vf_set_min_stack( code, 2 );
+ vf_set_min_stack( instr, 2 );
// create in vector
- vf_new_in_vector( code, 2, pool );
- vf_set_in_vector_stack_entry_double( code, 0 );
- return;
+ vf_new_in_vector( instr, 2, ctx->m_pool );
+ vf_set_in_vector_stack_entry_double( instr, 0 );
+ // set flag and make checks
+ vf_opcode_return( instr, next_pc, ctx );
} // vf_opcode_dreturn
/**
- * Function sets code instruction structure for opcode areturn.
+ * Sets instruction structure for opcode areturn.
*/
static inline void
-vf_opcode_areturn( vf_Code_t * code, // code instruction
- vf_VerifyPool_t * pool ) // memory pool
+vf_opcode_areturn( vf_Instr *instr, // a return instruction
+ unsigned short next_pc, // a start of the next instruction
+ vf_Context *ctx ) // verification context
{
- // set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// create in vector
- vf_new_in_vector( code, 1, pool );
- vf_set_in_vector_stack_entry_ref( code, 0, NULL );
- return;
+ vf_new_in_vector( instr, 1, ctx->m_pool );
+ vf_set_in_vector_stack_entry_ref( instr, 0,
+ ctx->m_method_outvector->m_vtype );
+
+ // set flag and make checks
+ vf_opcode_return( instr, next_pc, ctx );
} // vf_opcode_areturn
/**
- * Function sets code instruction structure for opcode getstatic.
+ * Sets instruction structure for opcode getstatic.
*/
-static inline Verifier_Result
-vf_opcode_getstatic( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_getstatic( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
result =
- vf_parse_const_pool( OPCODE_GETSTATIC, cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ vf_parse_const_pool( OPCODE_GETSTATIC, cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code, cp_parse.field.f_vlen );
+ vf_set_stack_modifier( instr, cp_parse.field.f_vlen );
// set stack out vector
- code->m_outvector = cp_parse.field.f_vector;
- code->m_outlen = ( unsigned short )cp_parse.field.f_vlen;
+ instr->m_outvector = cp_parse.field.f_vector;
+ instr->m_outlen = ( unsigned short )cp_parse.field.f_vlen;
return VER_OK;
} // vf_opcode_getstatic
/**
- * Function sets code instruction structure for opcode putstatic.
+ * Sets instruction structure for opcode putstatic.
*/
-static inline Verifier_Result
-vf_opcode_putstatic( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_putstatic( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
result =
- vf_parse_const_pool( OPCODE_PUTSTATIC, cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ vf_parse_const_pool( OPCODE_PUTSTATIC, cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code, -( int )cp_parse.field.f_vlen );
+ vf_set_stack_modifier( instr, -( int )cp_parse.field.f_vlen );
// set minimal stack for instruction
- vf_set_min_stack( code, cp_parse.field.f_vlen );
+ vf_set_min_stack( instr, cp_parse.field.f_vlen );
// set stack out vector
- code->m_invector = cp_parse.field.f_vector;
- code->m_inlen = ( unsigned short )cp_parse.field.f_vlen;
+ instr->m_invector = cp_parse.field.f_vector;
+ instr->m_inlen = ( unsigned short )cp_parse.field.f_vlen;
// set assign check
- vf_set_in_vector_check( code, code->m_inlen - 1, VF_CHECK_ASSIGN );
+ vf_set_in_vector_check( instr, instr->m_inlen - 1, VF_CHECK_ASSIGN );
return VER_OK;
} // vf_opcode_putstatic
/**
- * Function sets code instruction structure for opcode getfield.
+ * Sets instruction structure for opcode getfield.
*/
-static inline Verifier_Result
-vf_opcode_getfield( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_getfield( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
- result =
- vf_parse_const_pool( OPCODE_GETFIELD, cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ result = vf_parse_const_pool( OPCODE_GETFIELD, cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// set stack modifier for instruction, remove double this reference
- vf_set_stack_modifier( code, cp_parse.field.f_vlen - 2 );
+ vf_set_stack_modifier( instr, cp_parse.field.f_vlen - 2 );
// set minimal stack for instruction
- vf_set_min_stack( code, 1 );
+ vf_set_min_stack( instr, 1 );
// set stack in vector
- code->m_invector = cp_parse.field.f_vector;
- code->m_inlen = 1;
+ instr->m_invector = cp_parse.field.f_vector;
+ instr->m_inlen = 1;
// set field access check
- vf_set_in_vector_check( code, 0, VF_CHECK_ACCESS_FIELD );
- vf_set_in_vector_check_index( code, 0, cp_index );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_ACCESS_FIELD );
+ vf_set_in_vector_check_index( instr, 0, cp_index );
// set stack out vector, skip this reference
- code->m_outvector = cp_parse.field.f_vector + 1;
- code->m_outlen = ( unsigned short )cp_parse.field.f_vlen - 1;
+ instr->m_outvector = cp_parse.field.f_vector + 1;
+ instr->m_outlen = ( unsigned short )cp_parse.field.f_vlen - 1;
return VER_OK;
} // vf_opcode_getfield
/**
- * Function sets code instruction structure for opcode putfield.
+ * Sets instruction structure for opcode putfield.
*/
-static inline Verifier_Result
-vf_opcode_putfield( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_putfield( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
- result =
- vf_parse_const_pool( OPCODE_PUTFIELD, cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ result = vf_parse_const_pool( OPCODE_PUTFIELD, cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code, -cp_parse.field.f_vlen );
+ vf_set_stack_modifier( instr, -cp_parse.field.f_vlen );
// set minimal stack for instruction
- vf_set_min_stack( code, cp_parse.field.f_vlen );
+ vf_set_min_stack( instr, cp_parse.field.f_vlen );
// set stack in vector
- code->m_invector = cp_parse.field.f_vector;
- code->m_inlen = ( unsigned short )cp_parse.field.f_vlen;
+ instr->m_invector = cp_parse.field.f_vector;
+ instr->m_inlen = ( unsigned short )cp_parse.field.f_vlen;
// set assign check
- vf_set_in_vector_check( code, code->m_inlen - 1, VF_CHECK_ASSIGN );
+ vf_set_in_vector_check( instr, instr->m_inlen - 1, VF_CHECK_ASSIGN );
// set field access check
- vf_set_in_vector_check( code, 0, VF_CHECK_ACCESS_FIELD );
- vf_set_in_vector_check_index( code, 0, cp_index );
+ vf_set_in_vector_check( instr, 0, VF_CHECK_ACCESS_FIELD );
+ vf_set_in_vector_check_index( instr, 0, cp_index );
return VER_OK;
} // vf_opcode_putfield
/**
- * Function sets code instruction structure for invokes opcodes.
+ * Sets instruction structure for invokes opcodes.
*/
-static inline Verifier_Result
-vf_opcode_invoke( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_invoke( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
result =
- vf_parse_const_pool( *( code->m_addr ), cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ vf_parse_const_pool( *( instr->m_addr ), cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// check method name
if( cp_parse.method.m_name[0] == '<' ) {
- VERIFY_REPORT_METHOD( ctex,
- "Must call initializers using invokespecial" );
+ VF_REPORT( ctx, "Must call initializers using invokespecial" );
return VER_ErrorConstantPool;
}
// check number of arguments
if( cp_parse.method.m_inlen > 255 ) {
- VERIFY_REPORT_METHOD( ctex,
- "The number of method parameters is limited to 255" );
+ VF_REPORT( ctx, "The number of method parameters is limited to 255" );
return VER_ErrorInstruction;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code,
+ vf_set_stack_modifier( instr,
cp_parse.method.m_outlen -
cp_parse.method.m_inlen );
// set minimal stack for instruction
- vf_set_min_stack( code, cp_parse.method.m_inlen );
+ vf_set_min_stack( instr, cp_parse.method.m_inlen );
// set stack in vector
- code->m_invector = cp_parse.method.m_invector;
- code->m_inlen = ( unsigned short )cp_parse.method.m_inlen;
+ instr->m_invector = cp_parse.method.m_invector;
+ instr->m_inlen = ( unsigned short )cp_parse.method.m_inlen;
// set stack out vector
- code->m_outvector = cp_parse.method.m_outvector;
- code->m_outlen = ( unsigned short )cp_parse.method.m_outlen;
+ instr->m_outvector = cp_parse.method.m_outvector;
+ instr->m_outlen = ( unsigned short )cp_parse.method.m_outlen;
// set method access check for opcode invokevirtual
- if( ( *code->m_addr ) == OPCODE_INVOKEVIRTUAL ) {
- vf_set_in_vector_check( code, 0, VF_CHECK_ACCESS_METHOD );
- vf_set_in_vector_check_index( code, 0, cp_index );
+ if( ( *instr->m_addr ) == OPCODE_INVOKEVIRTUAL ) {
+ vf_set_in_vector_check( instr, 0, VF_CHECK_ACCESS_METHOD );
+ vf_set_in_vector_check_index( instr, 0, cp_index );
}
return VER_OK;
} // vf_opcode_invoke
/**
- * Function sets code instruction structure for invokes opcodes.
+ * Sets instruction structure for invokes opcodes.
*/
-static inline Verifier_Result
-vf_opcode_invokespecial( vf_Code_t * code, // code instruction
+static inline vf_Result
+vf_opcode_invokespecial( vf_Instr *instr, // code instruction
unsigned short cp_index, // constant pool entry index
- vf_Context_t * ctex ) // verifier context
+ vf_Context *ctx ) // verification context
{
- Verifier_Result result;
- vf_Parse_t cp_parse = { 0 };
+ vf_Result result;
+ vf_Parse cp_parse = { 0 };
// check constant pool for instruction
result =
- vf_parse_const_pool( *( code->m_addr ), cp_index, &cp_parse, ctex );
- if( result != VER_OK ) {
+ vf_parse_const_pool( *( instr->m_addr ), cp_index, &cp_parse, ctx );
+ if( VER_OK != result ) {
return result;
}
// check number of arguments
if( cp_parse.method.m_inlen > 255 ) {
- VERIFY_REPORT_METHOD( ctex,
- "The number of method parameters is limited to 255" );
+ VF_REPORT( ctx, "The number of method parameters is limited to 255" );
return VER_ErrorInstruction;
}
// set stack modifier for instruction
- vf_set_stack_modifier( code,
+ vf_set_stack_modifier( instr,
cp_parse.method.m_outlen -
cp_parse.method.m_inlen );
// set minimal stack for instruction
- vf_set_min_stack( code, cp_parse.method.m_inlen );
+ vf_set_min_stack( instr, cp_parse.method.m_inlen );
// set stack in vector
- code->m_invector = cp_parse.method.m_invector;
- code->m_inlen = ( unsigned short )cp_parse.method.m_inlen;
+ instr->m_invector = cp_parse.method.m_invector;
+ instr->m_inlen = ( unsigned short )cp_parse.method.m_inlen;
// set stack out vector
- code->m_outvector = cp_parse.method.m_outvector;
- code->m_outlen = ( unsigned short )cp_parse.method.m_outlen;
+ instr->m_outvector = cp_parse.method.m_outvector;
+ instr->m_outlen = ( unsigned short )cp_parse.method.m_outlen;
// set method check for opcode invokespecial
if( !strcmp( cp_parse.method.m_name, "jsr instructions and exception handlers.
+ * Also this guards against a case when parsing doesn't stop
+ * at the end of the method. If bc[len - 1] represents jsr_w,
+ * then bc[len + 4] will be marked with basic block end.
*/
- unsigned len = method_get_code_length( ctex->m_method );
- unsigned char *bytecode = method_get_bytecode( ctex->m_method );
- unsigned short locals = method_get_max_local( ctex->m_method );
+ vf_Pool *pool = ctx->m_pool;
+ vf_BCode *bc = (vf_BCode*)vf_palloc( pool, ( len + GOTO_W_LEN )
+ * sizeof( vf_BCode ) );
+ ctx->m_bc = bc;
// first instruction is always begin of basic block
- vf_BCode_t *bc = ctex->m_bc;
- bc[0].m_mark = 1;
+ bc[0].m_is_bb_start = true;
- /**
- * Parse bytecode instructions and fill a code array
- */
- unsigned instr;
+ // allocate memory for instructions
+ ctx->m_instr =
+ ( vf_InstrHandle )vf_palloc( pool, len * sizeof( vf_Instr ) );
+
+ int offset;
+ unsigned index, count;
+ unsigned short local, const_index;
+ unsigned char u1;
+ vf_Result result = VER_OK;
unsigned branches;
- unsigned codeNum = 0;
+ unsigned ret_num = 0;
+
+ vf_Instr *instr = (vf_Instr*)ctx->m_instr;
- vf_Code_t *code;
- vf_VerifyPool_t *pool = ctex->m_pool;
- for( index = 0; index < len; codeNum++ ) {
- code = &ctex->m_code[codeNum];
- code->m_addr = &bytecode[index];
- // Note:
- // bc[ index ].m_instr is assigned to a positive
- // value to differentiate with non-assignd values:
- // the correspondent index in vf_Context.m_code array
- // is increased by one.
- bc[index].m_instr = codeNum + 1;
+ // parse bytecode instructions and fill a instruction array
+ for( index = 0; index < len; instr++ ) {
+ instr->m_addr = &bytecode[index];
+ bc[index].m_instr = instr;
bool wide = ( OPCODE_WIDE == bytecode[index] ); /* 0xc4 */
if( wide ) {
@@ -4215,21 +3981,21 @@ vf_parse_bytecode( vf_Context_t * ctex )
case OPCODE_IINC:
break;
default:
- VERIFY_REPORT_METHOD( ctex,
- "Instruction wide should be followed "
- "by iload, fload, aload, lload, dload, istore, fstore, astore, "
- "lstore, dstore, ret or iinc" );
+ VF_REPORT( ctx,
+ "Instruction wide should be followed "
+ "by iload, fload, aload, lload, dload, istore, fstore, astore, "
+ "lstore, dstore, ret or iinc" );
return VER_ErrorInstruction;
}
}
- instr = index; // remember offset of instruction
+ unsigned prev_index = index; // remember offset of instruction
index++; // skip bytecode
- switch ( bytecode[instr] ) {
+ switch ( bytecode[prev_index] ) {
case OPCODE_NOP: /* 0x00 */
break;
case OPCODE_ACONST_NULL: /* 0x01 */
- vf_opcode_aconst_null( code, pool );
+ vf_opcode_aconst_null( instr, pool );
break;
case OPCODE_SIPUSH: /* 0x11 + s2 */
index++; // skip parameter (s2)
@@ -4242,28 +4008,28 @@ vf_parse_bytecode( vf_Context_t * ctex )
case OPCODE_ICONST_3: /* 0x06 */
case OPCODE_ICONST_4: /* 0x07 */
case OPCODE_ICONST_5: /* 0x08 */
- vf_opcode_iconst_n( code, pool );
+ vf_opcode_iconst_n( instr, pool );
break;
case OPCODE_LCONST_0: /* 0x09 */
case OPCODE_LCONST_1: /* 0x0a */
- vf_opcode_lconst_n( code, pool );
+ vf_opcode_lconst_n( instr, pool );
break;
case OPCODE_FCONST_0: /* 0x0b */
case OPCODE_FCONST_1: /* 0x0c */
case OPCODE_FCONST_2: /* 0x0d */
- vf_opcode_fconst_n( code, pool );
+ vf_opcode_fconst_n( instr, pool );
break;
case OPCODE_DCONST_0: /* 0x0e */
case OPCODE_DCONST_1: /* 0x0f */
- vf_opcode_dconst_n( code, pool );
+ vf_opcode_dconst_n( instr, pool );
break;
case OPCODE_LDC: /* 0x12 + u1 */
// get constant pool index
const_index = ( unsigned short )bytecode[index];
// skip constant pool index (u1)
index++;
- result = vf_opcode_ldcx( code, 1, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_ldcx( instr, 1, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4276,346 +4042,336 @@ vf_parse_bytecode( vf_Context_t * ctex )
// skip constant pool index (u2)
index += 2;
result =
- vf_opcode_ldcx( code, bytecode[instr] - OPCODE_LDC,
- const_index, ctex );
- if( result != VER_OK ) {
+ vf_opcode_ldcx( instr, bytecode[prev_index] - OPCODE_LDC,
+ const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
case OPCODE_ILOAD: /* 0x15 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_iloadx( code, local, pool );
+ vf_opcode_iloadx( instr, local, pool );
break;
case OPCODE_LLOAD: /* 0x16 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_lloadx( code, local, pool );
+ vf_opcode_lloadx( instr, local, pool );
break;
case OPCODE_FLOAD: /* 0x17 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_floadx( code, local, pool );
+ vf_opcode_floadx( instr, local, pool );
break;
case OPCODE_DLOAD: /* 0x18 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_dloadx( code, local, pool );
+ vf_opcode_dloadx( instr, local, pool );
break;
case OPCODE_ALOAD: /* 0x19 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_aloadx( code, local, pool );
+ vf_opcode_aloadx( instr, local, pool );
break;
case OPCODE_ILOAD_0: /* 0x1a */
case OPCODE_ILOAD_1: /* 0x1b */
case OPCODE_ILOAD_2: /* 0x1c */
case OPCODE_ILOAD_3: /* 0x1d */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_ILOAD_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_ILOAD_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_iloadx( code, local, pool );
+ vf_opcode_iloadx( instr, local, pool );
break;
case OPCODE_LLOAD_0: /* 0x1e */
case OPCODE_LLOAD_1: /* 0x1f */
case OPCODE_LLOAD_2: /* 0x20 */
case OPCODE_LLOAD_3: /* 0x21 */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_LLOAD_0 );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_LLOAD_0 );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_lloadx( code, local, pool );
+ vf_opcode_lloadx( instr, local, pool );
break;
case OPCODE_FLOAD_0: /* 0x22 */
case OPCODE_FLOAD_1: /* 0x23 */
case OPCODE_FLOAD_2: /* 0x24 */
case OPCODE_FLOAD_3: /* 0x25 */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_FLOAD_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_FLOAD_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_floadx( code, local, pool );
+ vf_opcode_floadx( instr, local, pool );
break;
case OPCODE_DLOAD_0: /* 0x26 */
case OPCODE_DLOAD_1: /* 0x27 */
case OPCODE_DLOAD_2: /* 0x28 */
case OPCODE_DLOAD_3: /* 0x29 */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_DLOAD_0 );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_DLOAD_0 );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_dloadx( code, local, pool );
+ vf_opcode_dloadx( instr, local, pool );
break;
case OPCODE_ALOAD_0: /* 0x2a */
case OPCODE_ALOAD_1: /* 0x2b */
case OPCODE_ALOAD_2: /* 0x2c */
case OPCODE_ALOAD_3: /* 0x2d */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_ALOAD_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_ALOAD_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_aloadx( code, local, pool );
+ vf_opcode_aloadx( instr, local, pool );
break;
case OPCODE_IALOAD: /* 0x2e */
- vf_opcode_iaload( code, ctex );
+ vf_opcode_iaload( instr, ctx );
break;
case OPCODE_BALOAD: /* 0x33 */
- vf_opcode_baload( code, ctex );
+ vf_opcode_baload( instr, ctx );
break;
case OPCODE_CALOAD: /* 0x34 */
- vf_opcode_caload( code, ctex );
+ vf_opcode_caload( instr, ctx );
break;
case OPCODE_SALOAD: /* 0x35 */
- vf_opcode_saload( code, ctex );
+ vf_opcode_saload( instr, ctx );
break;
case OPCODE_LALOAD: /* 0x2f */
- vf_opcode_laload( code, ctex );
+ vf_opcode_laload( instr, ctx );
break;
case OPCODE_FALOAD: /* 0x30 */
- vf_opcode_faload( code, ctex );
+ vf_opcode_faload( instr, ctx );
break;
case OPCODE_DALOAD: /* 0x31 */
- vf_opcode_daload( code, ctex );
+ vf_opcode_daload( instr, ctx );
break;
case OPCODE_AALOAD: /* 0x32 */
- vf_opcode_aaload( code, ctex );
+ vf_opcode_aaload( instr, ctx );
break;
case OPCODE_ISTORE: /* 0x36 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_istorex( code, local, pool );
+ vf_opcode_istorex( instr, local, pool );
break;
case OPCODE_LSTORE: /* 0x37 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_lstorex( code, local, pool );
+ vf_opcode_lstorex( instr, local, pool );
break;
case OPCODE_FSTORE: /* 0x38 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_fstorex( code, local, pool );
+ vf_opcode_fstorex( instr, local, pool );
break;
case OPCODE_DSTORE: /* 0x39 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_dstorex( code, local, pool );
+ vf_opcode_dstorex( instr, local, pool );
break;
case OPCODE_ASTORE: /* 0x3a + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_astorex( code, local, pool );
+ vf_opcode_astorex( instr, local, pool );
break;
case OPCODE_ISTORE_0: /* 0x3b */
case OPCODE_ISTORE_1: /* 0x3c */
case OPCODE_ISTORE_2: /* 0x3d */
case OPCODE_ISTORE_3: /* 0x3e */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_ISTORE_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_ISTORE_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_istorex( code, local, pool );
+ vf_opcode_istorex( instr, local, pool );
break;
case OPCODE_LSTORE_0: /* 0x3f */
case OPCODE_LSTORE_1: /* 0x40 */
case OPCODE_LSTORE_2: /* 0x41 */
case OPCODE_LSTORE_3: /* 0x42 */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_LSTORE_0 );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_LSTORE_0 );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_lstorex( code, local, pool );
+ vf_opcode_lstorex( instr, local, pool );
break;
case OPCODE_FSTORE_0: /* 0x43 */
case OPCODE_FSTORE_1: /* 0x44 */
case OPCODE_FSTORE_2: /* 0x45 */
case OPCODE_FSTORE_3: /* 0x46 */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_FSTORE_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_FSTORE_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_fstorex( code, local, pool );
+ vf_opcode_fstorex( instr, local, pool );
break;
case OPCODE_DSTORE_0: /* 0x47 */
case OPCODE_DSTORE_1: /* 0x48 */
case OPCODE_DSTORE_2: /* 0x49 */
case OPCODE_DSTORE_3: /* 0x4a */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_DSTORE_0 );
- result = vf_check_local_var_number( local + 1, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_DSTORE_0 );
+ result = vf_check_local_var_number( local + 1, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_dstorex( code, local, pool );
+ vf_opcode_dstorex( instr, local, pool );
break;
case OPCODE_ASTORE_0: /* 0x4b */
case OPCODE_ASTORE_1: /* 0x4c */
case OPCODE_ASTORE_2: /* 0x4d */
case OPCODE_ASTORE_3: /* 0x4e */
// get number of local variable
- local = ( unsigned short )( bytecode[instr] - OPCODE_ASTORE_0 );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local =
+ ( unsigned short )( bytecode[prev_index] - OPCODE_ASTORE_0 );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_astorex( code, local, pool );
+ vf_opcode_astorex( instr, local, pool );
break;
case OPCODE_IASTORE: /* 0x4f */
- vf_opcode_iastore( code, ctex );
+ vf_opcode_iastore( instr, ctx );
break;
case OPCODE_BASTORE: /* 0x54 */
- vf_opcode_bastore( code, ctex );
+ vf_opcode_bastore( instr, ctx );
break;
case OPCODE_CASTORE: /* 0x55 */
- vf_opcode_castore( code, ctex );
+ vf_opcode_castore( instr, ctx );
break;
case OPCODE_SASTORE: /* 0x56 */
- vf_opcode_sastore( code, ctex );
+ vf_opcode_sastore( instr, ctx );
break;
case OPCODE_LASTORE: /* 0x50 */
- vf_opcode_lastore( code, ctex );
+ vf_opcode_lastore( instr, ctx );
break;
case OPCODE_FASTORE: /* 0x51 */
- vf_opcode_fastore( code, ctex );
+ vf_opcode_fastore( instr, ctx );
break;
case OPCODE_DASTORE: /* 0x52 */
- vf_opcode_dastore( code, ctex );
+ vf_opcode_dastore( instr, ctx );
break;
case OPCODE_AASTORE: /* 0x53 */
- vf_opcode_aastore( code, ctex );
+ vf_opcode_aastore( instr, ctx );
break;
case OPCODE_POP: /* 0x57 */
- vf_opcode_pop( code, pool );
+ vf_opcode_pop( instr, pool );
break;
case OPCODE_POP2: /* 0x58 */
- vf_opcode_pop2( code, pool );
+ vf_opcode_pop2( instr, pool );
break;
case OPCODE_DUP: /* 0x59 */
- vf_opcode_dup( code, pool );
+ vf_opcode_dup( instr, pool );
break;
case OPCODE_DUP_X1: /* 0x5a */
- vf_opcode_dup_x1( code, pool );
+ vf_opcode_dup_x1( instr, pool );
break;
case OPCODE_DUP_X2: /* 0x5b */
- vf_opcode_dup_x2( code, pool );
+ vf_opcode_dup_x2( instr, pool );
break;
case OPCODE_DUP2: /* 0x5c */
- vf_opcode_dup2( code, pool );
+ vf_opcode_dup2( instr, pool );
break;
case OPCODE_DUP2_X1: /* 0x5d */
- vf_opcode_dup2_x1( code, pool );
+ vf_opcode_dup2_x1( instr, pool );
break;
case OPCODE_DUP2_X2: /* 0x5e */
- vf_opcode_dup2_x2( code, pool );
+ vf_opcode_dup2_x2( instr, pool );
break;
case OPCODE_SWAP: /* 0x5f */
- vf_opcode_swap( code, pool );
+ vf_opcode_swap( instr, pool );
break;
case OPCODE_IADD: /* 0x60 */
case OPCODE_ISUB: /* 0x64 */
case OPCODE_IMUL: /* 0x68 */
case OPCODE_IDIV: /* 0x6c */
case OPCODE_IREM: /* 0x70 */
- vf_opcode_iadd( code, pool );
+ vf_opcode_iadd( instr, pool );
break;
case OPCODE_LADD: /* 0x61 */
case OPCODE_LSUB: /* 0x65 */
case OPCODE_LMUL: /* 0x69 */
case OPCODE_LDIV: /* 0x6d */
case OPCODE_LREM: /* 0x71 */
- vf_opcode_ladd( code, pool );
+ vf_opcode_ladd( instr, pool );
break;
case OPCODE_FADD: /* 0x62 */
case OPCODE_FSUB: /* 0x66 */
case OPCODE_FMUL: /* 0x6a */
case OPCODE_FDIV: /* 0x6e */
case OPCODE_FREM: /* 0x72 */
- vf_opcode_fadd( code, pool );
+ vf_opcode_fadd( instr, pool );
break;
case OPCODE_DADD: /* 0x63 */
case OPCODE_DSUB: /* 0x67 */
case OPCODE_DMUL: /* 0x6b */
case OPCODE_DDIV: /* 0x6f */
case OPCODE_DREM: /* 0x73 */
- vf_opcode_dadd( code, pool );
+ vf_opcode_dadd( instr, pool );
break;
case OPCODE_INEG: /* 0x74 */
- vf_opcode_ineg( code, pool );
+ vf_opcode_ineg( instr, pool );
break;
case OPCODE_LNEG: /* 0x75 */
- vf_opcode_lneg( code, pool );
+ vf_opcode_lneg( instr, pool );
break;
case OPCODE_FNEG: /* 0x76 */
- vf_opcode_fneg( code, pool );
+ vf_opcode_fneg( instr, pool );
break;
case OPCODE_DNEG: /* 0x77 */
- vf_opcode_dneg( code, pool );
+ vf_opcode_dneg( instr, pool );
break;
case OPCODE_ISHL: /* 0x78 */
case OPCODE_ISHR: /* 0x7a */
@@ -4623,83 +4379,81 @@ vf_parse_bytecode( vf_Context_t * ctex )
case OPCODE_IAND: /* 0x7e */
case OPCODE_IOR: /* 0x80 */
case OPCODE_IXOR: /* 0x82 */
- vf_opcode_ibit( code, pool );
+ vf_opcode_ibit( instr, pool );
break;
case OPCODE_LSHL: /* 0x79 */
case OPCODE_LSHR: /* 0x7b */
case OPCODE_LUSHR: /* 0x7d */
- vf_opcode_lshx( code, pool );
+ vf_opcode_lshx( instr, pool );
break;
case OPCODE_LAND: /* 0x7f */
case OPCODE_LOR: /* 0x81 */
case OPCODE_LXOR: /* 0x83 */
- vf_opcode_land( code, pool );
+ vf_opcode_land( instr, pool );
break;
case OPCODE_IINC: /* 0x84 + u1|u2 + s1|s2 */
count = index;
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
count = index - count;
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_iinc( code, local, pool );
+ vf_opcode_iinc( instr, local, pool );
// skip 2nd parameter (s1|s2)
index += count;
break;
case OPCODE_I2L: /* 0x85 */
- vf_opcode_i2l( code, pool );
+ vf_opcode_i2l( instr, pool );
break;
case OPCODE_I2F: /* 0x86 */
- vf_opcode_i2f( code, pool );
+ vf_opcode_i2f( instr, pool );
break;
case OPCODE_I2D: /* 0x87 */
- vf_opcode_i2d( code, pool );
+ vf_opcode_i2d( instr, pool );
break;
case OPCODE_L2I: /* 0x88 */
- vf_opcode_l2i( code, pool );
+ vf_opcode_l2i( instr, pool );
break;
case OPCODE_L2F: /* 0x89 */
- vf_opcode_l2f( code, pool );
+ vf_opcode_l2f( instr, pool );
break;
case OPCODE_L2D: /* 0x8a */
- vf_opcode_l2d( code, pool );
+ vf_opcode_l2d( instr, pool );
break;
case OPCODE_F2I: /* 0x8b */
- vf_opcode_f2i( code, pool );
+ vf_opcode_f2i( instr, pool );
break;
case OPCODE_F2L: /* 0x8c */
- vf_opcode_f2l( code, pool );
+ vf_opcode_f2l( instr, pool );
break;
case OPCODE_F2D: /* 0x8d */
- vf_opcode_f2d( code, pool );
+ vf_opcode_f2d( instr, pool );
break;
case OPCODE_D2I: /* 0x8e */
- vf_opcode_d2i( code, pool );
+ vf_opcode_d2i( instr, pool );
break;
case OPCODE_D2L: /* 0x8f */
- vf_opcode_d2l( code, pool );
+ vf_opcode_d2l( instr, pool );
break;
case OPCODE_D2F: /* 0x90 */
- vf_opcode_d2f( code, pool );
+ vf_opcode_d2f( instr, pool );
break;
case OPCODE_I2B: /* 0x91 */
case OPCODE_I2C: /* 0x92 */
case OPCODE_I2S: /* 0x93 */
- vf_opcode_i2b( code, pool );
+ vf_opcode_i2b( instr, pool );
break;
case OPCODE_LCMP: /* 0x94 */
- vf_opcode_lcmp( code, pool );
+ vf_opcode_lcmp( instr, pool );
break;
case OPCODE_FCMPL: /* 0x95 */
case OPCODE_FCMPG: /* 0x96 */
- vf_opcode_fcmpx( code, pool );
+ vf_opcode_fcmpx( instr, pool );
break;
case OPCODE_DCMPL: /* 0x97 */
case OPCODE_DCMPG: /* 0x98 */
- vf_opcode_dcmpx( code, pool );
+ vf_opcode_dcmpx( instr, pool );
break;
case OPCODE_IFEQ: /* 0x99 + s2 */
case OPCODE_IFNE: /* 0x9a + s2 */
@@ -4707,18 +4461,18 @@ vf_parse_bytecode( vf_Context_t * ctex )
case OPCODE_IFGE: /* 0x9c + s2 */
case OPCODE_IFGT: /* 0x9d + s2 */
case OPCODE_IFLE: /* 0x9e + s2 */
- offset = vf_get_double_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_double_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( index, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_ifeq( code, &bc[offset], &bc[index], pool );
+ vf_opcode_ifeq( instr, &bc[offset], &bc[index], pool );
break;
case OPCODE_IF_ICMPEQ: /* 0x9f + s2 */
case OPCODE_IF_ICMPNE: /* 0xa0 + s2 */
@@ -4726,159 +4480,120 @@ vf_parse_bytecode( vf_Context_t * ctex )
case OPCODE_IF_ICMPGE: /* 0xa2 + s2 */
case OPCODE_IF_ICMPGT: /* 0xa3 + s2 */
case OPCODE_IF_ICMPLE: /* 0xa4 + s2 */
- offset = vf_get_double_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_double_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( index, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_if_icmpeq( code, &bc[offset], &bc[index], pool );
+ vf_opcode_if_icmpeq( instr, &bc[offset], &bc[index], pool );
break;
case OPCODE_IF_ACMPEQ: /* 0xa5 + s2 */
case OPCODE_IF_ACMPNE: /* 0xa6 + s2 */
- offset = vf_get_double_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_double_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( index, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_if_acmpeq( code, &bc[offset], &bc[index], pool );
+ vf_opcode_if_acmpeq( instr, &bc[offset], &bc[index], pool );
break;
case OPCODE_GOTO: /* 0xa7 + s2 */
- offset = vf_get_single_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_single_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_set_basic_block_flag( &bc[offset] );
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_set_basic_block_flag( index, ctx );
break;
case OPCODE_JSR: /* 0xa8 + s2 */
- offset = vf_get_single_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_single_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
- return result;
- }
- vf_opcode_jsr( code, codeNum, pool );
- ctex->m_dump.m_with_subroutine = 1;
- vf_set_basic_block_flag( &bc[offset] );
- vf_set_basic_block_flag( &bc[index] );
+ vf_opcode_jsr( instr, offset, pool );
+ vf_set_basic_block_flag( index, ctx );
break;
case OPCODE_RET: /* 0xa9 + u1|u2 */
- local =
- ( unsigned short )vf_get_local_var_number( code, bytecode,
- &index, wide );
- result = vf_check_local_var_number( local, locals, ctex );
- if( result != VER_OK ) {
+ local = vf_get_local_var_number( instr, bytecode, &index, wide );
+ result = vf_check_local_var_number( local, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_ret( code, local, pool );
+ vf_opcode_ret( instr, local, pool );
// create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_set_basic_block_flag( index, ctx );
+ ret_num++;
break;
case OPCODE_TABLESWITCH: /* 0xaa + pad + s4 * (3 + N) */
- vf_opcode_switch( code, pool );
- branches = vf_set_tableswitch_offsets( code,
- instr, &index, bytecode,
- pool );
+ vf_opcode_switch( instr, pool );
+ branches = vf_set_tableswitch_offsets( instr,
+ prev_index, &index,
+ bytecode, pool );
// check tableswitch branches and set begin of basic blocks
for( count = 0; count < branches; count++ ) {
- offset = vf_get_code_branch( code, count );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ offset = vf_get_instr_branch( instr, count );
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_set_basic_block_flag( &bc[offset] );
}
if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
+ vf_set_basic_block_flag( index, ctx );
}
break;
case OPCODE_LOOKUPSWITCH: /* 0xab + pad + s4 * 2 * (N + 1) */
- vf_opcode_switch( code, pool );
- result = vf_set_lookupswitch_offsets( code,
- instr, &index, bytecode,
- &branches, ctex );
- if( result != VER_OK ) {
+ vf_opcode_switch( instr, pool );
+ result = vf_set_lookupswitch_offsets( instr,
+ prev_index, &index,
+ bytecode, &branches, ctx );
+ if( VER_OK != result ) {
return result;
}
// check tableswitch branches and set begin of basic blocks
for( count = 0; count < branches; count++ ) {
- offset = vf_get_code_branch( code, count );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ offset = vf_get_instr_branch( instr, count );
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_set_basic_block_flag( &bc[offset] );
}
if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
+ vf_set_basic_block_flag( index, ctx );
}
break;
case OPCODE_IRETURN: /* 0xac */
- vf_opcode_ireturn( code, pool );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_ireturn( instr, index, ctx );
break;
case OPCODE_LRETURN: /* 0xad */
- vf_opcode_lreturn( code, pool );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_lreturn( instr, index, ctx );
break;
case OPCODE_FRETURN: /* 0xae */
- vf_opcode_freturn( code, pool );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_freturn( instr, index, ctx );
break;
case OPCODE_DRETURN: /* 0xaf */
- vf_opcode_dreturn( code, pool );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_dreturn( instr, index, ctx );
break;
case OPCODE_ARETURN: /* 0xb0 */
- vf_opcode_areturn( code, pool );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_areturn( instr, index, ctx );
break;
case OPCODE_RETURN: /* 0xb1 */
- // set instruction flag
- vf_set_code_type( code, VF_TYPE_INSTR_RETURN );
- // create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_opcode_return( instr, index, ctx );
break;
case OPCODE_GETSTATIC: /* 0xb2 + u2 */
// get constant pool index
@@ -4887,8 +4602,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_getstatic( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_getstatic( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4899,8 +4614,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_putstatic( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_putstatic( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4911,8 +4626,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_getfield( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_getfield( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4923,8 +4638,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_putfield( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_putfield( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4935,8 +4650,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_invoke( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_invoke( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4947,8 +4662,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_invokespecial( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_invokespecial( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4959,8 +4674,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_invoke( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_invoke( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -4971,16 +4686,14 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_invoke( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_invoke( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
// check the number of arguments and last opcode byte
- if( ctex->m_code[codeNum].m_inlen !=
- ( unsigned short )bytecode[index]
+ if( instr->m_inlen != ( unsigned short )bytecode[index]
|| bytecode[index + 1] != 0 ) {
- VERIFY_REPORT_METHOD( ctex,
- "Incorrect operand byte of invokeinterface" );
+ VF_REPORT( ctx, "Incorrect operand byte of invokeinterface" );
return VER_ErrorInstruction;
}
// skip 2 parameters (u1 + u1)
@@ -4993,9 +4706,12 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- // Zero number of opcode new is reserved for "uninitialized this"
- result = vf_opcode_new( code, const_index, codeNum + 1, ctex );
- if( result != VER_OK ) {
+ // zero number of opcode new is reserved for "uninitialized this"
+ result =
+ vf_opcode_new( instr, const_index, instr - ctx->m_instr + 1,
+ ctx );
+
+ if( VER_OK != result ) {
return result;
}
break;
@@ -5004,8 +4720,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
u1 = ( unsigned char )bytecode[index];
// skip parameter (u1)
index++;
- result = vf_opcode_newarray( code, u1, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_newarray( instr, u1, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -5016,20 +4732,18 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_anewarray( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_anewarray( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
case OPCODE_ARRAYLENGTH: /* 0xbe */
- vf_opcode_arraylength( code, ctex );
+ vf_opcode_arraylength( instr, ctx );
break;
case OPCODE_ATHROW: /* 0xbf */
- vf_opcode_athrow( code, ctex );
+ vf_opcode_athrow( instr, ctx );
// create and set edge branch to exit
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_set_basic_block_flag( index, ctx );
break;
case OPCODE_CHECKCAST: /* 0xc0 + u2 */
// get constant pool index
@@ -5038,8 +4752,8 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_checkcast( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_checkcast( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
@@ -5050,14 +4764,14 @@ vf_parse_bytecode( vf_Context_t * ctex )
( bytecode[index + 1] ) );
// skip constant pool index (u2)
index += 2;
- result = vf_opcode_instanceof( code, const_index, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_instanceof( instr, const_index, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
case OPCODE_MONITORENTER: /* 0xc2 */
case OPCODE_MONITOREXIT: /* 0xc3 */
- vf_opcode_monitorx( code, pool );
+ vf_opcode_monitorx( instr, pool );
break;
case OPCODE_MULTIANEWARRAY: /* 0xc5 + u2 + u1 */
// get constant pool index
@@ -5070,286 +4784,206 @@ vf_parse_bytecode( vf_Context_t * ctex )
u1 = bytecode[index];
// skip dimensions of array (u1)
index++;
- result = vf_opcode_multianewarray( code, const_index, u1, ctex );
- if( result != VER_OK ) {
+ result = vf_opcode_multianewarray( instr, const_index, u1, ctx );
+ if( VER_OK != result ) {
return result;
}
break;
case OPCODE_IFNULL: /* 0xc6 + s2 */
case OPCODE_IFNONNULL: /* 0xc7 + s2 */
- offset = vf_get_double_hword_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_double_hword_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( index, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_ifxnull( &ctex->m_code[codeNum], &bc[offset],
- &bc[index], pool );
+ vf_opcode_ifxnull( instr, &bc[offset], &bc[index], pool );
break;
case OPCODE_GOTO_W: /* 0xc8 + s4 */
- offset = vf_get_single_word_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_single_word_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_set_basic_block_flag( &bc[offset] );
- if( index < len ) {
- vf_set_basic_block_flag( &bc[index] );
- }
+ vf_set_basic_block_flag( index, ctx );
break;
case OPCODE_JSR_W: /* 0xc9 + s4 */
- offset = vf_get_single_word_branch_offset( code,
- instr, bytecode,
+ offset = vf_get_single_word_branch_offset( instr,
+ prev_index, bytecode,
&index, pool );
- result = vf_check_branch_offset( offset, len, ctex );
- if( result != VER_OK ) {
- return result;
- }
- result = vf_check_branch_offset( index, len, ctex );
- if( result != VER_OK ) {
+ result = vf_check_branch_offset( offset, ctx );
+ if( VER_OK != result ) {
return result;
}
- vf_opcode_jsr( code, codeNum, pool );
- ctex->m_dump.m_with_subroutine = 1;
- vf_set_basic_block_flag( &bc[offset] );
- vf_set_basic_block_flag( &bc[index] );
+ vf_opcode_jsr( instr, offset, pool );
+ vf_set_basic_block_flag( index, ctx );
break;
case _OPCODE_UNDEFINED: /* 0xba */
default:
- VERIFY_REPORT_METHOD( ctex, "Unknown bytecode instruction " );
+ VF_REPORT( ctx, "Unknown bytecode instruction " );
return VER_ErrorInstruction;
}
}
if( index > len ) {
- VERIFY_REPORT_METHOD( ctex,
- "The last instruction doesn't fit bytecode array" );
+ VF_REPORT( ctx, "The last instruction doesn't fit bytecode array" );
return VER_ErrorInstruction;
}
/**
* Set handler basic blocks.
*/
- unsigned short handler_count =
- method_get_exc_handler_number( ctex->m_method );
- unsigned short constLen = class_get_cp_size( ctex->m_class );
+ unsigned short handler_count = ctx->m_handlers;
+ unsigned short constLen = class_get_cp_size( ctx->m_class );
for( unsigned short handler_index = 0;
handler_index < handler_count; handler_index++ ) {
unsigned short start_pc, end_pc, handler_pc, handler_cp_index;
- method_get_exc_handler_info( ctex->m_method,
+ method_get_exc_handler_info( ctx->m_method,
handler_index, &start_pc, &end_pc,
&handler_pc, &handler_cp_index );
// check instruction range
if( ( start_pc >= len )
|| ( end_pc > len )
|| ( handler_pc >= len ) ) {
- VERIFY_REPORT_METHOD( ctex,
- "Exception handler pc is out of range" );
+ VF_REPORT( ctx, "Exception handler pc is out of range" );
return VER_ErrorHandler;
}
if( start_pc >= end_pc ) {
- VERIFY_REPORT_METHOD( ctex,
- "Exception handler range starting point should be before ending point" );
+ VF_REPORT( ctx,
+ "Exception handler range starting point should be before ending point" );
return VER_ErrorHandler;
}
// check that handlers point to instruction
// boundaries
- if( bc[start_pc].m_instr == 0
- || bc[end_pc].m_instr == 0 || bc[handler_pc].m_instr == 0 ) {
- VERIFY_REPORT_METHOD( ctex, "Exception handler parameters ["
- << start_pc << ", " << end_pc << ", " <<
- handler_pc <<
- "] are out of instruction set" );
+ if( NULL == bc[start_pc].m_instr
+ || NULL == bc[end_pc].m_instr
+ || NULL == bc[handler_pc].m_instr ) {
+ VF_REPORT( ctx,
+ "At least one of exception handler parameters ["
+ << start_pc << ", " << end_pc << ", " <<
+ handler_pc << "] are out of instruction set" );
return VER_ErrorHandler;
}
- bc[start_pc].m_mark = 1;
- if( end_pc < len ) {
- bc[end_pc].m_mark = 1;
- }
- bc[handler_pc].m_mark = 1;
+ bc[start_pc].m_is_bb_start = true;
+ bc[end_pc].m_is_bb_start = true;
+ bc[handler_pc].m_is_bb_start = true;
}
- /**
- * Count edges from basic blocks from exception range to the
- * corresponding exception handlers.
- */
- unsigned edges = 0;
- for( unsigned short handler_index = 0;
- handler_index < handler_count; handler_index++ ) {
- unsigned short start_pc, end_pc, handler_pc, handler_cp_index;
- method_get_exc_handler_info( ctex->m_method, handler_index,
- &start_pc, &end_pc, &handler_pc,
- &handler_cp_index );
-
- // number of basic blocks in the exception range
- unsigned handler_edges = 0;
- for( count = start_pc; count < end_pc; count++ ) {
- handler_edges += bc[count].m_mark;
- }
-
- edges += handler_edges;
- }
-
- /**
- * Initialize a node counter with handler nodes
- * and 2 terminator nodes.
- */
- unsigned nodes = handler_count + 2;
-
- /**
- * Check code offsets, count basic blocks and edges.
- */
- for( index = 0; index < len; index++ ) {
- instr = bc[index].m_instr;
- if( instr == 0 ) {
- if( bc[index].m_mark ) {
- VERIFY_REPORT_METHOD( ctex,
- "Illegal target of jump or branch" );
- return VER_ErrorBranch;
- } else {
- continue;
- }
- }
-
- code = &ctex->m_code[instr - 1];
- if( bc[index].m_mark ) {
- code->m_basic_block_start = true;
- nodes++;
- }
-
- if( code->m_offcount ) {
- // basic block should start next, so we will
- // count one branch anyway
- edges += code->m_offcount - 1;
- }
- }
-
- /**
- * Each node except the ending node emits at least one branch.
- */
- edges += nodes - 1;
-
// store context values
- ctex->m_codeNum = codeNum;
- ctex->m_nodeNum = nodes;
- ctex->m_edgeNum = edges;
-
-#if _VERIFY_DEBUG
- if( ctex->m_dump.m_code ) {
- vf_dump_bytecode( ctex );
- }
-#endif // _VERIFY_DEBUG
+ ctx->m_last_instr = instr;
+ ctx->m_retnum = ret_num;
+ VF_DUMP( DUMP_INSTR, vf_dump_bytecode( ctx ) );
return result;
} // vf_parse_bytecode
-#if _VERIFY_DEBUG
+#if _VF_DEBUG
/**
- * Function prints code instruction array in stream.
+ * Prints code instruction array in stream.
*/
void
-vf_dump_bytecode( vf_Context_t * ctex ) // verifier context
+vf_dump_bytecode( vf_ContextHandle ctx ) // verification context
{
- VERIFY_DEBUG
+ VF_DEBUG
( "======================== VERIFIER METHOD DUMP ========================" );
- VERIFY_DEBUG( "Method: " << class_get_name( ctex->m_class )
- << "." << method_get_name( ctex->m_method )
- << method_get_descriptor( ctex->m_method ) << endl );
- VERIFY_DEBUG( "0 [-]: -> START-ENTRY" );
+ VF_DEBUG( "Method: " << class_get_name( ctx->m_class )
+ << "." << method_get_name( ctx->m_method )
+ << method_get_descriptor( ctx->m_method ) << endl );
+ VF_DEBUG( "0 [-]: -> START-ENTRY" );
- unsigned short handler_count =
- method_get_exc_handler_number( ctex->m_method );
+ unsigned short handler_count = ctx->m_handlers;
for( unsigned short handler_index = 0;
handler_index < handler_count; handler_index++ ) {
- VERIFY_DEBUG( handler_index +
- 1 << " [-]: -> HANDLER #" << handler_index + 1 );
+ VF_DEBUG( handler_index +
+ 1 << " [-]: -> HANDLER #" << handler_index + 1 );
unsigned short start_pc, end_pc, handler_pc, handler_cp_index;
- method_get_exc_handler_info( ctex->m_method,
+ method_get_exc_handler_info( ctx->m_method,
handler_index, &start_pc, &end_pc,
&handler_pc, &handler_cp_index );
- VERIFY_DEBUG( " from " << ctex->m_bc[start_pc].m_instr + handler_count
- << " [" << start_pc << "]"
- " to " << ctex->m_bc[end_pc].m_instr + handler_count
- << " [" << end_pc << "]"
- " --> " << ctex->m_bc[handler_pc].m_instr +
- handler_count << " [" << handler_pc << "]" ", CP type "
- << handler_cp_index );
- }
-
- unsigned char *bytecode = method_get_bytecode( ctex->m_method );
- unsigned end_code = ctex->m_codeNum + handler_count + 1;
- vf_Code_t *code = ctex->m_code;
- for( unsigned index = handler_count + 1;
- index < end_code; index++, code++ ) {
- VERIFY_DEBUG( index
- << " [" << code->m_addr - bytecode << "]:"
- << ( ( code->m_basic_block_start ) ? " -> " : " " )
- << ( ( code->m_stack < 0 ) ? "" : " " )
- << code->m_stack
- << "|" << code->m_minstack << " "
- << vf_opcode_names[*( code->m_addr )] );
- for( unsigned count = 0; count < code->m_offcount; count++ ) {
- unsigned offset = code->m_off[count];
- VERIFY_DEBUG( " --> "
- << ctex->m_bc[offset].m_instr + handler_count
- << " [" << offset << "]" );
+ VF_DEBUG( " from " << vf_bc_to_instr_index( start_pc, ctx ) +
+ handler_count << " [" << start_pc << "]" " to " <<
+ vf_bc_to_instr_index( end_pc,
+ ctx ) +
+ handler_count << " [" << end_pc << "]" " --> " <<
+ vf_bc_to_instr_index( handler_pc,
+ ctx ) +
+ handler_count << " [" << handler_pc << "]" ", CP type "
+ << handler_cp_index );
+ }
+
+ unsigned char *bytecode = method_get_bytecode( ctx->m_method );
+ vf_InstrHandle instr = ctx->m_instr;
+ unsigned index;
+ for( index = handler_count + 1;
+ instr < ctx->m_last_instr; index++, instr++ ) {
+ VF_DEBUG( index
+ << " [" << instr->m_addr - bytecode << "]:"
+ << ( ( instr->m_is_bb_start ) ? " -> " : " " )
+ << ( ( instr->m_stack < 0 ) ? "" : " " )
+ << instr->m_stack
+ << "|" << instr->m_minstack << " "
+ << vf_opcode_names[*( instr->m_addr )] );
+ for( unsigned count = 0; count < instr->m_offcount; count++ ) {
+ unsigned offset = instr->m_off[count];
+ VF_DEBUG( " --> "
+ << vf_bc_to_instr_index( offset,
+ ctx ) +
+ handler_count << " [" << offset << "]" );
}
}
- VERIFY_DEBUG( end_code << " [-]: -> END-ENTRY" << endl );
- VERIFY_DEBUG
+ VF_DEBUG( index << " [-]: -> END-ENTRY" << endl );
+ VF_DEBUG
( "======================================================================" );
- return;
} // vf_dump_bytecode
-#endif //_VERIFY_DEBUG
+#endif //_VF_DEBUG
/**
- * Function provides initial verification of class.
+ * Provides initial verification of class.
*/
-Verifier_Result
+vf_Result
vf_verify_class( class_handler klass, // verified class
unsigned verifyAll, // verification level flag
char **message ) // verifier error message
{
assert( klass );
assert( message );
-#if VERIFY_CLASS
+#if VF_CLASS
if( strcmp( class_get_name( klass ), "" ) ) {
return VER_OK;
}
-#endif // VERIFY_CLASS
+#endif // VF_CLASS
- VERIFY_TRACE( "class.bytecode",
- "verify class: " << class_get_name( klass ) );
+ VF_TRACE( "class.bytecode", "verify class: " << class_get_name( klass ) );
/**
* Create context
*/
- vf_Context_t context;
+ vf_Context ctx;
/**
* Set current class
*/
- context.m_class = klass;
+ ctx.m_class = klass;
/**
* Create type pool
*/
- context.m_type = new vf_TypePool();
+ ctx.m_type = new vf_TypePool();
/**
* Create memory pool
*/
- context.m_pool = vf_create_pool();
+ ctx.m_pool = vf_create_pool();
/**
* Set valid types
@@ -5361,77 +4995,60 @@ vf_verify_class( class_handler klass,
memcpy( &type_name[1], class_name, class_name_len );
type_name[0] = 'L';
type_name[class_name_len + 1] = '\0';
- context.m_vtype.m_class =
- context.m_type->NewType( type_name, class_name_len + 1 );
- context.m_vtype.m_throwable =
- context.m_type->NewType( "Ljava/lang/Throwable", 20 );
- context.m_vtype.m_object =
- context.m_type->NewType( "Ljava/lang/Object", 17 );
- context.m_vtype.m_array =
- context.m_type->NewType( "[Ljava/lang/Object", 18 );
- context.m_vtype.m_clone =
- context.m_type->NewType( "Ljava/lang/Cloneable", 20 );
- context.m_vtype.m_serialize =
- context.m_type->NewType( "Ljava/io/Serializable", 21 );
+ ctx.m_vtype.m_class =
+ ctx.m_type->NewType( type_name, class_name_len + 1 );
+ ctx.m_vtype.m_throwable =
+ ctx.m_type->NewType( "Ljava/lang/Throwable", 20 );
+ ctx.m_vtype.m_object = ctx.m_type->NewType( "Ljava/lang/Object", 17 );
+ ctx.m_vtype.m_array = ctx.m_type->NewType( "[Ljava/lang/Object", 18 );
+ ctx.m_vtype.m_clone = ctx.m_type->NewType( "Ljava/lang/Cloneable", 20 );
+ ctx.m_vtype.m_serialize =
+ ctx.m_type->NewType( "Ljava/io/Serializable", 21 );
/**
* Set verification level flag
*/
- context.m_dump.m_verify = verifyAll ? 1 : 0;
+ ctx.m_verify_all = verifyAll ? true : false;
/**
* Verify bytecode of methods
*/
- Verifier_Result result = VER_OK;
+ vf_Result result = VER_OK;
unsigned short number = class_get_method_number( klass );
for( unsigned short index = 0; index < number; index++ ) {
-#if VERIFY_METHOD
+#if VF_METHOD
if( !strcmp
( method_get_name( class_get_method( klass, index ) ), "" ) )
-#endif // VERIFY_METHOD
+#endif // VF_METHOD
{
/**
* Set verified method
*/
- context.m_method = class_get_method( klass, index );
- //context.m_dump.m_node_vector = 1;
- //context.m_dump.m_code_vector = 1;
- //context.m_dump.m_merge_vector = 1;
- //context.m_dump.m_dot_graph = 1;
- result = vf_verify_method_bytecode( &context );
- context.ClearContext();
+ ctx.SetMethod( class_get_method( klass, index ) );
+ result = vf_verify_method_bytecode( &ctx );
+ ctx.ClearContext();
}
- if( result == VER_NoSupportJSR ) {
- result = VER_OK;
- } else if( result != VER_OK ) {
+ if( VER_OK != result ) {
goto labelEnd_verifyClass;
}
}
- /**
- * Check and set class constraints
- */
-#if _VERIFY_DEBUG
- if( context.m_dump.m_constraint ) {
- context.m_type->DumpTypeConstraints( NULL );
- }
-#endif // _VERIFY_DEBUG
- result = vf_check_class_constraints( &context );
- if( result != VER_OK ) {
+ VF_DUMP( DUMP_CONSTRAINT, ctx.m_type->DumpTypeConstraints( NULL ) );
+
+ // check and set class constraints
+ result = vf_check_class_constraints( &ctx );
+ if( VER_OK != result ) {
goto labelEnd_verifyClass;
}
labelEnd_verifyClass:
- vf_delete_pool( context.m_pool );
- delete context.m_type;
- *message = context.m_error;
-#if _VERIFY_DEBUG
- if( result != VER_OK ) {
- TRACE2( "verifier",
- "VerifyError: " << ( context.m_error ? context.
- m_error : "NULL" ) );
+ *message = ctx.m_error;
+#if _VF_DEBUG
+ if( VER_OK != result ) {
+ VF_TRACE( "",
+ "VerifyError: " << ( ctx.m_error ? ctx.m_error : "NULL" ) );
}
-#endif // _VERIFY_DEBUG
+#endif // _VF_DEBUG
return result;
} // vf_verify_class