Block implements code analysis and block implements code

Source: Internet
Author: User
Tags constant definition

Block implements code analysis and block implements code
Internal Structure of the block

First, write a block.

void exampleBlock() {    // NSConcreteStackBlock    int a = 1;    __block int b = 2;    int(^blockTest0)(int c) = ^(int c){        return a + b + c;    };    int c = 3;    blockTest0(c);    // NSConcreteGlobalBlock    void(^blockTest2)(void) = ^(void){        ;    };    blockTest2();}

Convert clang to c for analysis

clang -rewrite-objc block.c

We can see that their definition is

struct __exampleBlock_block_impl_0 {  struct __block_impl impl;  struct __exampleBlock_block_desc_0* Desc;  int a;  __Block_byref_b_0 *b; // by ref  __exampleBlock_block_impl_0(void *fp, struct __exampleBlock_block_desc_0 *desc, int _a, __Block_byref_b_0 *_b, int flags=0) : a(_a), b(_b->__forwarding) {    impl.isa = &_NSConcreteStackBlock;    impl.Flags = flags;    impl.FuncPtr = fp;    Desc = desc;  }};// __block_implstruct __block_impl {  void *isa;  int Flags;  int Reserved;  void *FuncPtr;};// __exampleBlock_block_desc_0struct __exampleBlock_block_impl_0 {  struct __block_impl impl;  struct __exampleBlock_block_desc_0* Desc;  int a;  __Block_byref_b_0 *b; // by ref  __exampleBlock_block_impl_0(void *fp, struct __exampleBlock_block_desc_0 *desc, int _a, __Block_byref_b_0 *_b, int flags=0) : a(_a), b(_b->__forwarding) {    impl.isa = &_NSConcreteStackBlock;    impl.Flags = flags;    impl.FuncPtr = fp;    Desc = desc;  }};// __exampleBlock_block_impl_2struct __exampleBlock_block_impl_2 {  struct __block_impl impl;  struct __exampleBlock_block_desc_2* Desc;  __exampleBlock_block_impl_2(void *fp, struct __exampleBlock_block_desc_2 *desc, int flags=0) {    impl.isa = &_NSConcreteStackBlock;    impl.Flags = flags;    impl.FuncPtr = fp;    Desc = desc;  }};

Initialize and execute code

void exampleBlock() {    // blockTest0    int a = 1;    __attribute__((__blocks__(byref))) __Block_byref_b_0 b = {(void*)0,(__Block_byref_b_0 *)&b, 0, sizeof(__Block_byref_b_0), 2};    int(*blockTest0)(int c) = (int (*)(int))&__exampleBlock_block_impl_0((void *)__exampleBlock_block_func_0, &__exampleBlock_block_desc_0_DATA, a, (__Block_byref_b_0 *)&b, 570425344);    int c = 3;    ((int (*)(__block_impl *, int))((__block_impl *)blockTest0)->FuncPtr)((__block_impl *)blockTest0, c);    // blockTest2    void(*blockTest2)(void) = (void (*)())&__exampleBlock_block_impl_2((void *)__exampleBlock_block_func_2, &__exampleBlock_block_desc_2_DATA);    ((void (*)(__block_impl *))((__block_impl *)blockTest2)->FuncPtr)((__block_impl *)blockTest2);}

Let's take a look at blockTest2, which is composed of the impl struct, the Desc struct, And the constructor _ exampleBlock_block_impl_2 ().

  • * Isa points to the Instance Object (the code isNSConcreteStackBlock, which is actuallyNSConcreteGlobalBlock)
  • Flags is used to indicate additional block information in bit.
  • Reserved variable
  • * FuncPtr function pointer pointing to the address of the function call implemented by the specific block (in the code, _ exampleBlock_block_func_2)
static void __exampleBlock_block_func_2(struct __exampleBlock_block_impl_2 *__cself) {        ;}
  • Size_t reserved. The input value is 0.
  • Block_size struct size
static struct __exampleBlock_block_desc_2 {  size_t reserved;  size_t Block_size;} __exampleBlock_block_desc_2_DATA = { 0, sizeof(struct __exampleBlock_block_impl_2)};

Then we are looking at blockTest, which has two more variables a and B than blockTest2.

  • Int a; external variable,

  • Block_byref_ B _0 * B; added block-modified B, which isBlock_byref_ B _0

Three additional input values are included in the generated initialization code.

    int(*blockTest0)(int c) = (int (*)(int))&__exampleBlock_block_impl_0((void *)__exampleBlock_block_func_0, &__exampleBlock_block_desc_0_DATA, a, (__Block_byref_b_0 *)&b, 570425344);
  • A is that this is directly passed in, And then copied to

  • B is the transfer address. It is to assign _ Block_byref_ B _0 to B.

The _ Block_byref_ B _0 struct is

struct __Block_byref_b_0 {  void *__isa;__Block_byref_b_0 *__forwarding; int __flags; int __size; int b;};

_ Forwarding is a pointer to itself.

The initialization code of _ Block_byref_ B _0 is as follows:

__attribute__((__blocks__(byref))) __Block_byref_b_0 b = {(void*)0,(__Block_byref_b_0 *)&b, 0, sizeof(__Block_byref_b_0), 2};

We can see that a is directly copied in, B is transferred to a struct, and then the pointer of this struct is passed in, so block cannot modify a and B.

  • 570425344 this should be passed to Flags

The Desc and blockTest2 of blockTest0 are also different.

static struct __exampleBlock_block_desc_0 {  size_t reserved;  size_t Block_size;  void (*copy)(struct __exampleBlock_block_impl_0*, struct __exampleBlock_block_impl_0*);  void (*dispose)(struct __exampleBlock_block_impl_0*);} __exampleBlock_block_desc_0_DATA = { 0, sizeof(struct __exampleBlock_block_impl_0), __exampleBlock_block_copy_0, __exampleBlock_block_dispose_0};

There are two more function pointers: copy and dispose. The reference count of the corresponding variables before and after the call is modified, pointing

static void __exampleBlock_block_copy_0(struct __exampleBlock_block_impl_0*dst, struct __exampleBlock_block_impl_0*src) {_Block_object_assign((void*)&dst->b, (void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/);}static void __exampleBlock_block_dispose_0(struct __exampleBlock_block_impl_0*src) {_Block_object_dispose((void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/);}

Let's take a look at * FuncPtr of blockTest0.

 static int __exampleBlock_block_func_0(struct __exampleBlock_block_impl_0 *__cself, int c) {  __Block_byref_b_0 *b = __cself->b; // bound by ref  int a = __cself->a; // bound by copy        return a + (b->__forwarding->b) + c;    }

We can see that a uses the copied a, and B uses the B in the struct.


Append 200 points and expand the pl0 code to provide useful websites

Let me give it to your website. I have been looking for it for a long time. That thing is quite needed.
Download.csdn.net/source/191218
PL/0 is a subset of Pascal. The PL/0 Compilation Program analyzed here includes PL/0
Class PCODE code is analyzed, compiled and generated by the language source program, and the generated class PCODE code function is interpreted on the virtual machine.
The PL/0 language compilation program uses the syntax analysis as the core and the scanning method. Lexical Analysis and code generation are independent subprograms for the syntax analysis program to call. Syntax analysis also provides Error Reporting and error recovery. If the source program does not pass the compilation error, call the class PCODE interpreter to explain and execute the generated class PCODE code.
2. Description of each function module

Lexical analysis subroutine analysis:
The name of the lexical analysis subroutine is GETSYM. The function is to read a word symbol (TOTAKEN) from the source program, put its information into the global variables SYM, ID, and NUM, and put the character variables into CH, when the syntax analyzer needs words, it obtains them directly from these three variables. The Getch process repeatedly calls the Getch subprocess to obtain characters from the source program and splice them into words. The row Buffer technology is used in the GETCH process to improve the program running efficiency.
Lexical analyzer analysis process: When GETSYM is called, it obtains a character from the source program through the GETCH process. If the character is a letter, you can continue to get the character or number, and finally combine it into a word to query the reserved word table. If it is found to be a reserved word, the SYM variable is assigned to the corresponding reserved word type value; if not found, the word should be a user-defined identifier (may be a variable name, constant name, or process name), and SYM is set to IDENT, store the word in the ID variable. Binary lookup is used to query reserved word tables to improve efficiency. If the characters obtained by Getch are numbers, continue to use Getch to obtain the numbers, splice them into an INTEGER or REAL number, and then set SYM to INTEGER or REAL, put the assembled value into the NUM variable. If other valid symbols (such as value assignment, greater than or less than or equal to) are identified, SYM is of the corresponding type. If an invalid character is encountered, set SYM to NUL.

Syntax analysis subroutine analysis:
Syntax analysis subprograms use top-down recursive subprograms. syntax analysis also generates the corresponding ternary code based on the Program semantics, and provides an error processing mechanism. Syntax analysis mainly consists of the program analysis process (BLOCK), parameter variable analysis process (ParaDeclaration), parameter variable processing process (ParaGetSub), and array processing process (ParaGetSub) constant definition analysis process (ConstDeclaration), variable definition analysis process (Vardeclaration), Statement analysis process (Statement), Expression Processing Process (Expression), Term processing process (Term), Factor and Condition. These processes form a nested hierarchy. In addition, there are Error reporting, code generation, Test, and Enter processes) query the Position function and the auxiliary process of syntax analysis for listing the class PCODE code process (Listcode.
A complete PL/0 program consists of a division program and a period. Therefore, when the compilation program is running, the sub-program processing block is called in the main program to analyze the sub-program part (the Sub-program analysis process may also recursively call the block process ), then ...... remaining full text>

Java analyzes the Code Execution Process and outputs the results

Static is a static Declaration, so when the Employee. id is executed first, the static script will be executed first, that is, the default value assignment of the id and the execution of the static block, that is, printing the static_block
So the process is. Assign a value id to print static_block. The above code is to print static_block and Main: 0.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.