JVM test

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
lynxeyed_atsu
Date:
Mon Aug 26 15:02:07 2013 +0000
Parent:
5:047542b65d00
Child:
7:2a384a077520
Commit message:
Fixed to boot class file from flash.

Changed in this revision

device_depend.cpp Show annotated file Show diff for this revision Revisions of this file
device_depend.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
pool.h Show annotated file Show diff for this revision Revisions of this file
ravem.cpp Show annotated file Show diff for this revision Revisions of this file
ravem.h Show annotated file Show diff for this revision Revisions of this file
--- a/device_depend.cpp	Sat Aug 24 07:00:51 2013 +0000
+++ b/device_depend.cpp	Mon Aug 26 15:02:07 2013 +0000
@@ -2,11 +2,18 @@
 #include <string.h>
 #include "device_depend.h"
 
+#define bc_str_length 1024 // from 32 to 1024
+
+
+Serial pc(USBTX, USBRX); // tx, rx
+LocalFileSystem local("local");
+FILE* ReadFile;
+Ticker tick;
 
 volatile static unsigned long msTicks;                            /* counts 1ms timeTicks */
+char bc_str[bc_str_length];
+int last_bc_num = 0;
 
-Serial pc(USBTX, USBRX); // tx, rx
-Ticker tick;
 void hardware_init(void){
 	setup_systick();
 }
@@ -32,6 +39,33 @@
 	//bit = value;
 }
 
+void bytecode_read_init(void){
+
+	if(NULL == (ReadFile = fopen ("/local/Test.cla","rb"))){ uart_print(" ERROR:Can't read class File.\r\n"); while(1); }
+	fseek(ReadFile, 0, SEEK_SET);
+	// I don't know why, but fseek does not work right. So I use fgetc instead.
+	//fgets(bc_str, bc_str_length, ReadFile);
+	printf("loading...");
+	for(int i = 0; i < bc_str_length; i++) bc_str[i] = fgetc(ReadFile);
+	printf("end\r\n");
+	//last_bc_num = bc_str_length;
+}
+
+char* bytecode_read(int bc_num, int length){
+	
+	if((last_bc_num <= bc_num)&&(bc_num < last_bc_num + bc_str_length)&&(length <= bc_str_length)){ // exists data in buffer
+		return &bc_str[bc_num - last_bc_num];
+	}else
+	{
+		fseek(ReadFile, bc_num, SEEK_SET);
+		for(int i = 0; i < bc_str_length; i++)
+		{
+			bc_str[i] = fgetc(ReadFile);
+		}
+		last_bc_num = bc_num;
+	}
+	return bc_str;
+}
 
 /*----------------------------------------------------------------------------
   SysTick_Handler
--- a/device_depend.h	Sat Aug 24 07:00:51 2013 +0000
+++ b/device_depend.h	Mon Aug 26 15:02:07 2013 +0000
@@ -3,6 +3,7 @@
 
 #include "mbed.h"
 
+
 // functions
 void hardware_init(void);
 void uart_init(int baud_rate);
@@ -11,7 +12,10 @@
 int time_millis(void);
 void port_write(int port, int bit, int value);
 
+void bytecode_read_init(void);
+char* bytecode_read(int bc_num, int length);
 void setup_systick(void);
 
 #endif
 
+
--- a/main.cpp	Sat Aug 24 07:00:51 2013 +0000
+++ b/main.cpp	Mon Aug 26 15:02:07 2013 +0000
@@ -9,6 +9,7 @@
     
     hardware_init();    
     uart_init(9600);
+    bc_init();
     pool_init();
     
     uart_print("LPC11U24 mbed JVM Start\r\n");
@@ -39,78 +40,72 @@
             }
         }           
         switch(p[0].threadCommand){
-            case Thread_getInitMethodWithStack:
+        case Thread_getInitMethodWithStack:
+            thread_count++;
+        
+            p = (class_st *)pool_realloc((int *)p,sizeof(class_st)*(1 + thread_count));
+            if(p == NULL)uart_print("error!");  
+            p[thread_count] = seekCodeArrtibute(p[thread_count], "<init>", 6);  // init
+            p[thread_count].field_mem_reg = NULL;
+            p[thread_count].field_num = 0;
+            p[thread_count].local_reg = (int *)pool_alloc(sizeof(int) * p[thread_count].local_num);
+            p[thread_count].op_stack_type = (int *)pool_alloc(sizeof(int) * p[thread_count].stack_num);
+            p[thread_count].op_stack = (int *)pool_alloc(sizeof(int) * p[thread_count].stack_num);  
+            p[thread_count].op_stack_type[0] = 0;           
+            p[thread_count].threadCommand = Thread_init;
+            
+            // copy stack -> local variable
+            for(lp = p[0].threadArg+1; lp != 0 ; lp--){
+                p[thread_count].local_reg[lp] = getIntegerFromOperandStack(p[0]);
+            }
+                        
+            while(p[thread_count].threadCommand != Thread_returned){
+                p[thread_count] = decodeVM(p[thread_count]);
+            }
+            
+            p[thread_count].threadCommand = Thread_initIsDone;
+            p[0].threadCommand = Thread_Active;    
+            break;
+            
+        case Thread_getStartMethod:
+            for(lp = 0 ; lp <= thread_count + 1 ; lp++){
+                if(p[lp].threadCommand == Thread_initIsDone)break;
+            }
+            if(p[lp].threadCommand != Thread_initIsDone){
                 thread_count++;
-            
-                p = (class_st *)pool_realloc((int *)p,sizeof(class_st)*(1 + thread_count));
+                p = (class_st *)pool_realloc((int *)p,sizeof(class_st)*(1+thread_count));
                 if(p == NULL)uart_print("error!");  
-                p[thread_count] = seekCodeArrtibute(p[thread_count], "<init>", 6);  // init
-                p[thread_count].field_mem_reg = NULL;
-                p[thread_count].field_num = 0;
-                p[thread_count].local_reg = (int *)pool_alloc(sizeof(int) * p[thread_count].local_num);
-                p[thread_count].op_stack_type = (int *)pool_alloc(sizeof(int) * p[thread_count].stack_num);
-                p[thread_count].op_stack = (int *)pool_alloc(sizeof(int) * p[thread_count].stack_num);  
-                p[thread_count].op_stack_type[0] = 0;           
-                p[thread_count].threadCommand = Thread_init;
-                
-                // copy stack -> local variable
-                for(lp = p[0].threadArg+1; lp != 0 ; lp--){
-                    p[thread_count].local_reg[lp] = getIntegerFromOperandStack(p[0]);
-                }
-                            
-                while(p[thread_count].threadCommand != Thread_returned){
-                    p[thread_count] = decodeVM(p[thread_count]);
-                }
-                
-                p[thread_count].threadCommand = Thread_initIsDone;
-                p[0].threadCommand = Thread_Active;
-                
-                
-//              uart_print("Thread Active!\r\n");
-//              
-                break;
+                lp = thread_count;
                 
-            case Thread_getStartMethod:
-                for(lp = 0 ; lp <= thread_count + 1 ; lp++){
-                    if(p[lp].threadCommand == Thread_initIsDone)break;
-                }
-                
-                if(p[lp].threadCommand != Thread_initIsDone){
-                    uart_print("new\r\n");
-                    thread_count++;
-                    p = (class_st *)pool_realloc((int *)p,sizeof(class_st)*(1+thread_count));
-                    if(p == NULL)uart_print("error!");  
-                    lp = thread_count;
-                    
-                    p[lp] = seekCodeArrtibute(p[lp], "run", 3); // run method(start() calls this method)
-                            
-                    p[lp].local_reg = (int *)pool_alloc(sizeof(int) * p[lp].local_num);
-                    if(p[lp].local_reg == NULL)uart_print("error!");
-                    p[lp].op_stack_type = (int *)pool_alloc(sizeof(int) * p[lp].stack_num);
-                    if(p[lp].op_stack_type == NULL)uart_print("error!");
-                    p[lp].op_stack = (int *)pool_alloc( sizeof(int) * p[lp].stack_num);
-                    if(p[lp].op_stack == NULL)uart_print("error!");             
-                    p[lp].op_stack_type[0] = 0;
-                    p[lp].threadCommand = Thread_Active;
-                    p[lp].myThreadNum = lp;
-                    p[0].threadCommand = Thread_Active;
-                    break;
-                }
-                    
                 p[lp] = seekCodeArrtibute(p[lp], "run", 3); // run method(start() calls this method)
-                if(p[lp].local_reg == NULL)uart_print("pointr error!\r\n");     
-                p[lp].local_reg = (int *)pool_realloc(p[lp].local_reg, sizeof(int) * p[lp].local_num);
-                if(p[lp].local_reg == NULL)uart_print("pointr error!\r\n");
-                p[lp].op_stack_type = (int *)pool_realloc(p[lp].op_stack_type,sizeof(int) * p[lp].stack_num);
-                if(p[lp].op_stack_type == NULL)uart_print("pointr error!\r\n");
-                p[lp].op_stack = (int *)pool_realloc(p[lp].op_stack, sizeof(int) * p[lp].stack_num);
-                if(p[lp].op_stack == NULL)uart_print("pointr error!\r\n");          
+                        
+                p[lp].local_reg = (int *)pool_alloc(sizeof(int) * p[lp].local_num);
+                if(p[lp].local_reg == NULL)uart_print("error!");
+                p[lp].op_stack_type = (int *)pool_alloc(sizeof(int) * p[lp].stack_num);
+                if(p[lp].op_stack_type == NULL)uart_print("error!");
+                p[lp].op_stack = (int *)pool_alloc( sizeof(int) * p[lp].stack_num);
+                if(p[lp].op_stack == NULL)uart_print("error!");             
                 p[lp].op_stack_type[0] = 0;
                 p[lp].threadCommand = Thread_Active;
                 p[lp].myThreadNum = lp;
                 p[0].threadCommand = Thread_Active;
-                
-                break;              
+                break;
+            }
+                    
+            p[lp] = seekCodeArrtibute(p[lp], "run", 3); // run method(start() calls this method)
+            if(p[lp].local_reg == NULL)uart_print("pointr error!\r\n");     
+            p[lp].local_reg = (int *)pool_realloc(p[lp].local_reg, sizeof(int) * p[lp].local_num);
+            if(p[lp].local_reg == NULL)uart_print("pointr error!\r\n");
+            p[lp].op_stack_type = (int *)pool_realloc(p[lp].op_stack_type,sizeof(int) * p[lp].stack_num);
+            if(p[lp].op_stack_type == NULL)uart_print("pointr error!\r\n");
+            p[lp].op_stack = (int *)pool_realloc(p[lp].op_stack, sizeof(int) * p[lp].stack_num);
+            if(p[lp].op_stack == NULL)uart_print("pointr error!\r\n");          
+            p[lp].op_stack_type[0] = 0;
+            p[lp].threadCommand = Thread_Active;
+            p[lp].myThreadNum = lp;
+            p[0].threadCommand = Thread_Active;
+            
+            break;              
         }
         method_all_end = 0;
         for(lp = 0 ; lp < thread_count + 1 ; lp++){
@@ -125,7 +120,7 @@
         pool_free(p[lp].op_stack_type);
         pool_free(p[lp].op_stack);
     }
-  pool_free((int *)&p);
+    pool_free((int *)&p);
     
     p = NULL;
     
--- a/pool.h	Sat Aug 24 07:00:51 2013 +0000
+++ b/pool.h	Mon Aug 26 15:02:07 2013 +0000
@@ -1,41 +1,41 @@
-//
-//  pool.h
-//  
-//
-//  Created by atsu on 13/08/20.
-//
-//
-
-#ifndef POOL_H_
-#define POOL_H_
+//
+//  pool.h
+//  
+//
+//  Created by atsu on 13/08/20.
+//
+//
+
+#ifndef POOL_H_
+#define POOL_H_
 
 #include <stdio.h>
 #include <string.h>
 #include "device_depend.h"
 
-
-#define memory_available    1
-#define memory_invalid      0
-#define pool_size           256 // 256 * 4 = 1kByte
-#define magic_value         0xDEADDEAD
-//#define USE_MAGIC
-
-typedef struct {
-    int *first_pointer;
-    int *next_pointer;
-    int pool_size_all;
-    int available;
-}pool_all;
-
-typedef struct {
-    int **this_pointer;
-    int my_size;
-    int available;
-#if defined(USE_MAGIC)
-    int magic_num;
-#endif
+
+#define memory_available    1
+#define memory_invalid      0
+#define pool_size           256 // 256 * (sizeof(int)) = 1kByte
+#define magic_value         0xDEADDEAD
+//#define USE_MAGIC
+
+typedef struct {
+    int *first_pointer;
+    int *next_pointer;
+    int pool_size_all;
+    int available;
+}pool_all;
+
+typedef struct {
+    int **this_pointer;
+    int my_size;
+    int available;
+#if defined(USE_MAGIC)
+    int magic_num;
+#endif
 }pool_each;
-
+
 extern int pl_buf[pool_size];
 void pool_init(void);
 void pool_free(int *pointr);
@@ -43,6 +43,6 @@
 int *pool_realloc(int *pointr, int size);
 
 
-
-#endif
 
+#endif
+
--- a/ravem.cpp	Sat Aug 24 07:00:51 2013 +0000
+++ b/ravem.cpp	Mon Aug 26 15:02:07 2013 +0000
@@ -9,8 +9,10 @@
 #include "ravem.h"
 
 
+
+/*
 const unsigned char vm_array[] = {
-0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x32, 0x00, 0x35, 0x0A, 0x00, 0x0F, 
+	0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x32, 0x00, 0x35, 0x0A, 0x00, 0x0F, 
 	0x00, 0x1B, 0x09, 0x00, 0x1C, 0x00, 0x1D, 0x08, 0x00, 0x1E, 0x0A, 0x00, 0x1F, 0x00, 0x20, 0x0A, 
 	0x00, 0x0B, 0x00, 0x21, 0x0A, 0x00, 0x1F, 0x00, 0x22, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 	0x03, 0xE8, 0x0A, 0x00, 0x0B, 0x00, 0x23, 0x07, 0x00, 0x24, 0x07, 0x00, 0x25, 0x0A, 0x00, 0x0B, 
@@ -60,15 +62,17 @@
 	0x17, 0x00, 0x20, 0x00, 0x18, 0x00, 0x01, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1A, 0x00, 
 	0x00, 0x00
 };
-
+*/
 char cp_str[32];
-uint8_t bc_str[32];
 int32_t total_const_pool_num;
 int32_t methods_count;
 
-uint8_t *bc_seek(int bc_num, int length){
-	memcpy(bc_str, &vm_array[bc_num],length);
-	return bc_str;
+void bc_init(void){
+	bytecode_read_init();
+}
+char *bc_seek(int bc_num, int length){
+
+	return bytecode_read(bc_num, length);
 }
 
 int32_t getLengthOfConstantInfo(uint8_t constantType)
--- a/ravem.h	Sat Aug 24 07:00:51 2013 +0000
+++ b/ravem.h	Mon Aug 26 15:02:07 2013 +0000
@@ -15,97 +15,97 @@
 
 // constant_pool
 //#define Constant_Type				Value		length (in bytes)
-#define CONSTANT_Class				7					// 3
-#define	CONSTANT_Fieldref			9					// 5
-#define	CONSTANT_Methodref		10				// 5
-#define	CONSTANT_InterfaceMethodref	11	// 5
-#define	CONSTANT_String				8					// 3
-#define	CONSTANT_Integer			3					// 5
-#define	CONSTANT_Float				4					// 5
-#define	CONSTANT_Long					5					// 9
-#define	CONSTANT_Double				6					// 9
+#define CONSTANT_Class				7			// 3
+#define	CONSTANT_Fieldref			9			// 5
+#define	CONSTANT_Methodref			10			// 5
+#define	CONSTANT_InterfaceMethodref	11			// 5
+#define	CONSTANT_String				8			// 3
+#define	CONSTANT_Integer			3			// 5
+#define	CONSTANT_Float				4			// 5
+#define	CONSTANT_Long				5			// 9
+#define	CONSTANT_Double				6			// 9
 #define	CONSTANT_NameAndType		12			// 5
-#define	CONSTANT_Utf8						1				// 4 or more (see 'length')
+#define	CONSTANT_Utf8				1			// 4 or more (see 'length')
 #define	CONSTANT_MethodHandle		15			// 5
 #define	CONSTANT_MethodType			16			// 3
-#define	CONSTANT_InvokeDynamic	18			// 3
+#define	CONSTANT_InvokeDynamic		18			// 3
 
 //stack type
-#define Stack_Nothing 			0
-#define Stack_CharType			1
-#define Stack_IntType				2
-#define Stack_DoubleType		3
+#define Stack_Nothing 		0
+#define Stack_CharType		1
+#define Stack_IntType		2
+#define Stack_DoubleType	3
 #define Stack_ConstantPool	4
 
 //Thread State and Command
-#define Thread_returned									0
-#define Thread_Active										1
-#define Thread_getStartMethod						2
-#define Thread_getInitMethod						3
+#define Thread_returned						0
+#define Thread_Active						1
+#define Thread_getStartMethod				2
+#define Thread_getInitMethod				3
 #define Thread_getInitMethodWithStack		4
-#define Thread_init											5	
-#define Thread_initIsDone								6	
-#define	Thread_inSleep									7
+#define Thread_init							5	
+#define Thread_initIsDone					6	
+#define	Thread_inSleep						7
 
-// instruction code			mnemonic code		number of arguments
-#define JAVA_nop								0x00					// 0
-#define JAVA_iconst_0						0x03					// 0
-#define JAVA_iconst_1						0x04					// 0
-#define JAVA_iconst_2						0x05					// 0
-#define JAVA_iconst_3						0x06					// 0
-#define JAVA_iconst_4						0x07					// 0
-#define JAVA_iconst_5						0x08					// 0
-#define JAVA_bipush							0x10					// 1
-#define JAVA_sipush							0x11					// 2
-#define JAVA_ldc								0x12					// 1
-//#define JAVA_ldc_w							0x13					// xxx
-#define JAVA_ldc2_w							0x14					// 2
+// instruction code					mnemonic code		number of arguments
+#define JAVA_nop					0x00					// 0
+#define JAVA_iconst_0				0x03					// 0
+#define JAVA_iconst_1				0x04					// 0
+#define JAVA_iconst_2				0x05					// 0
+#define JAVA_iconst_3				0x06					// 0
+#define JAVA_iconst_4				0x07					// 0
+#define JAVA_iconst_5				0x08					// 0
+#define JAVA_bipush					0x10					// 1
+#define JAVA_sipush					0x11					// 2
+#define JAVA_ldc					0x12					// 1
+//#define JAVA_ldc_w				0x13					// xxx
+#define JAVA_ldc2_w					0x14					// 2
 
-#define JAVA_aload							0x19					// 1
+#define JAVA_aload					0x19					// 1
 
-#define JAVA_iload_0						0x1A					// 0
-#define JAVA_iload_1						0x1B					// 0
-#define JAVA_iload_2						0x1C					// 0
-#define JAVA_iload_3						0x1D					// 0
+#define JAVA_iload_0				0x1A					// 0
+#define JAVA_iload_1				0x1B					// 0
+#define JAVA_iload_2				0x1C					// 0
+#define JAVA_iload_3				0x1D					// 0
 
-#define JAVA_aload_0						0x2a					// 0
-#define JAVA_aload_1						0x2b					// 0
-#define JAVA_aload_2						0x2c					// 0
-#define JAVA_aload_3						0x2d					// 0
+#define JAVA_aload_0				0x2a					// 0
+#define JAVA_aload_1				0x2b					// 0
+#define JAVA_aload_2				0x2c					// 0
+#define JAVA_aload_3				0x2d					// 0
 
-#define JAVA_astore							0x3A					// 1
+#define JAVA_astore					0x3A					// 1
 
-#define JAVA_istore_0						0x3B					// 0
-#define JAVA_istore_1						0x3C					// 0
-#define JAVA_istore_2						0x3D					// 0
-#define JAVA_istore_3						0x3E					// 0
+#define JAVA_istore_0				0x3B					// 0
+#define JAVA_istore_1				0x3C					// 0
+#define JAVA_istore_2				0x3D					// 0
+#define JAVA_istore_3				0x3E					// 0
 
-#define JAVA_astore_0						0x4b					// 0
-#define JAVA_astore_1						0x4c					// 0
-#define JAVA_astore_2						0x4d					// 0
-#define JAVA_astore_3						0x4e					// 0
+#define JAVA_astore_0				0x4b					// 0
+#define JAVA_astore_1				0x4c					// 0
+#define JAVA_astore_2				0x4d					// 0
+#define JAVA_astore_3				0x4e					// 0
 
-#define	JAVA_dup								0x59					// 0
+#define	JAVA_dup					0x59					// 0
 
-#define JAVA_iadd								0x60					// 0
+#define JAVA_iadd					0x60					// 0
 
-#define JAVA_i2l								0x85					// 0
-#define JAVA_i2c								0x92					// 0
+#define JAVA_i2l					0x85					// 0
+#define JAVA_i2c					0x92					// 0
 
-#define JAVA_goto								0xa7					// 2
-#define JAVA_return							0xb1					// 0
-#define JAVA_getstatic					0xb2					// 2
-#define JAVA_getfield						0xb4					// 2
-#define JAVA_putfield						0xb5					// 2
+#define JAVA_goto					0xa7					// 2
+#define JAVA_return					0xb1					// 0
+#define JAVA_getstatic				0xb2					// 2
+#define JAVA_getfield				0xb4					// 2
+#define JAVA_putfield				0xb5					// 2
 #define JAVA_invokevirtual			0xb6					// 2
 #define JAVA_invokespecial			0xb7					// 2  //not imprement
-#define JAVA_invokestatic				0xb8					// 2
+#define JAVA_invokestatic			0xb8					// 2
 
-#define JAVA_new								0xbb					// 2
+#define JAVA_new					0xbb					// 2
 
 
 typedef struct {
-  int		tag;
+	int		tag;
 	int		index;
 	int		index2;
 	int		bc_num;		//pointer of bytecode
@@ -114,18 +114,18 @@
 
 
 typedef struct {
-	int bc_offset;				// offset of bytecode (this class starts here = bc_array[bc_offset]) 
-	int code_offset;			// offset of code (Now we translate here from bc_offset = bc_array[bc_offset+code_offset] )
-	int code_length;			// length of code
-		int stack_num;				// number of stacks
-	int local_num;				// number of local registers
-	int field_num;				// number of field length
-	int myThreadNum;			// Number of this thread(you must put #0 "main" method, and do not put #0 any other methods)
+	int bc_offset;			// offset of bytecode (this class starts here = bc_array[bc_offset]) 
+	int code_offset;		// offset of code (Now we translate here from bc_offset = bc_array[bc_offset+code_offset] )
+	int code_length;		// length of code
+	int stack_num;			// number of stacks
+	int local_num;			// number of local registers
+	int field_num;			// number of field length
+	int myThreadNum;		// Number of this thread(you must put #0 "main" method, and do not put #0 any other methods)
 	int	threadCommand;		// 
 	int	threadArg;
 	
-	int *local_reg;				// local registers(malloc here)
-	int *op_stack;				// operand stack(malloc here) numerics or CP num
+	int *local_reg;			// local registers(malloc here)
+	int *op_stack;			// operand stack(malloc here) numerics or CP num
 	int *op_stack_type;		// type of each stack,0:nothing 1:int,byte 2:long,float,double 3:See CP 
 
 	int *field_mem_reg;		// Field (getfield and putfield)
@@ -134,17 +134,19 @@
 } class_st;
 
 extern int32_t methods_count;
-uint8_t *bc_seek(int bc_num, int length);
+
+void bc_init(void);
+char *bc_seek(int bc_num, int length);
 const_pool_t getConstantPoolInfo(int constant_num);
 const_pool_t seekConstClassNumString(int const_num);
 const_pool_t seekClassIndex(int const_num);
 const_pool_t seekNameAndType_name(int const_num);
 const_pool_t seekNameAndType_desc(int const_num);
-class_st seekCodeArrtibute(class_st cl, char* method_name,int strlen);
 //
 int getIntegerFromOperandStack(class_st cl);
 char* getStringFromOperandStack(class_st cl);
 //
+class_st seekCodeArrtibute(class_st cl, char* method_name, int strlen);
 class_st setStackFromConstantPool(class_st cl, int cp_num);
 class_st setIntegerToStack(class_st cl, int num);
 //