// File: menhits[P]phplus/src/PhplusStdLib.cpp
// Function: populateMemManagementFuncs()
void populateMemManagementFuncs()
{
	globalNamespace->addNode(
		AstWhatevToActionFactory::make(
			[](Type leftType, Type rightType) -> Action
			{
				if (!leftType->isVoid() || rightType->isVoid())
					return nullptr;
				
				return lambdaAction(
					leftType,
					rightType,
					rightType->getPtr(),
					
					[=](void* leftIn, void* rightIn) -> void*
					{
						size_t size=rightType->getSize();
						void ** dataPtr=(void**)malloc(sizeof(void*));
						*dataPtr=malloc(size);
						memcpy(*dataPtr, rightIn, size);
						return dataPtr;
					},
					
					[=](Action inLeft, Action inRight, CppProgram* prog)
					{
						prog->code("&");
						prog->pushExpr();
							string typeCode=prog->getTypeCode(rightType);
							prog->code("(*(" + typeCode + "*)malloc(sizeof(" + typeCode + ")))");
							prog->code(" = ");
							prog->pushExpr();
								inRight->addToProg(prog);
							prog->popExpr();
						prog->popExpr();
						
						//"&((*($type)malloc(sizeof($type)))=($data))"
					},
					"new"
				);
			}
		),
		"new"
	);
	
	globalNamespace->addNode(
		AstWhatevToActionFactory::make(
			[](Type leftType, Type rightType) -> Action
			{
				if (leftType->getType()!=TypeBase::PTR || leftType->isVoid() || !rightType->isVoid())
					return nullptr;
				
				return lambdaAction(
					leftType,
					rightType,
					leftType->getSubType(),
					
					[=](void* leftIn, void* rightIn) -> void*
					{
						size_t size=leftType->getSubType()->getSize();
						void * data=malloc(size);
						memcpy(data, *(void**)leftIn, size);
						return data;
					},
					
					[=](Action inLeft, Action inRight, CppProgram* prog)
					{
						prog->code("*");
						prog->pushExpr();
							inLeft->addToProg(prog);
						prog->popExpr();
					},
					"dif"
				);
			}
		),
		"dif"
	);
	
	globalNamespace->addNode(
		AstWhatevToActionFactory::make(
			[](Type leftType, Type rightType) -> Action
			{
				if (leftType->getType()!=TypeBase::PTR || !rightType->matches(leftType->getSubType()))
					return nullptr;
				
				return lambdaAction(
					leftType,
					rightType,
					Void,
					
					[=](void* leftIn, void* rightIn) -> void*
					{
						memcpy(*(void**)leftIn, rightIn, rightType->getSize());
						return nullptr;
					},
					
					[=](Action inLeft, Action inRight, CppProgram* prog)
					{
						prog->code("*");
						prog->pushExpr();
							inLeft->addToProg(prog);
						prog->popExpr();
						prog->code(" = ");
						prog->pushExpr();
							inRight->addToProg(prog);
						prog->popExpr();
					},
					"dif"
				);
			}
		),
		"dif"
	);
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
leaq 0xb915a(%rip), %rdi     # 0x118428
callq 0x1a6a0
movq %rax, 0x40(%rsp)
leaq 0x140(%rsp), %rdi
movq %rdi, 0x48(%rsp)
leaq 0x13f(%rsp), %rsi
callq 0x5f660
movq 0x48(%rsp), %rsi
leaq 0x160(%rsp), %rdi
callq 0x96f70
jmp 0x5f306
leaq 0x107(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0xb690
movq 0x38(%rsp), %rdx
leaq 0x7298a(%rip), %rsi     # 0xd1cae
leaq 0x108(%rsp), %rdi
callq 0xb4c0
jmp 0x5f333
movq 0x40(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x3b150
jmp 0x5f34f
leaq 0x108(%rsp), %rdi
callq 0xb6e8
leaq 0x107(%rsp), %rdi
callq 0xb3f0
leaq 0x160(%rsp), %rdi
callq 0x1b3f0
leaq 0x140(%rsp), %rdi
callq 0x97050
leaq 0xb909e(%rip), %rdi     # 0x118428
callq 0x1a6a0
movq %rax, 0x28(%rsp)
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x30(%rsp)
leaq 0xd7(%rsp), %rsi
callq 0x5f6f0
movq 0x30(%rsp), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x96f70
jmp 0x5f3c2
leaq 0xaf(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xb690
movq 0x20(%rsp), %rdx
leaq 0x761b9(%rip), %rsi     # 0xd5599
leaq 0xb0(%rsp), %rdi
callq 0xb4c0
jmp 0x5f3ef
movq 0x28(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
callq 0x3b150
jmp 0x5f40b
leaq 0xb0(%rsp), %rdi
callq 0xb6e8
leaq 0xaf(%rsp), %rdi
callq 0xb3f0
leaq 0xf8(%rsp), %rdi
callq 0x1b3f0
leaq 0xd8(%rsp), %rdi
callq 0x97050
leaq 0xb8fe2(%rip), %rdi     # 0x118428
callq 0x1a6a0
movq %rax, 0x10(%rsp)
leaq 0x80(%rsp), %rdi
movq %rdi, 0x18(%rsp)
leaq 0x7f(%rsp), %rsi
callq 0x5f780
movq 0x18(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
callq 0x96f70
jmp 0x5f47b
leaq 0x57(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xb690
movq 0x8(%rsp), %rdx
leaq 0x76103(%rip), %rsi     # 0xd5599
leaq 0x58(%rsp), %rdi
callq 0xb4c0
jmp 0x5f4a2
movq 0x10(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0x58(%rsp), %rdx
callq 0x3b150
jmp 0x5f4bb
leaq 0x58(%rsp), %rdi
callq 0xb6e8
leaq 0x57(%rsp), %rdi
callq 0xb3f0
leaq 0xa0(%rsp), %rdi
callq 0x1b3f0
leaq 0x80(%rsp), %rdi
callq 0x97050
addq $0x168, %rsp            # imm = 0x168
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f558
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f53e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x108(%rsp), %rdi
callq 0xb6e8
leaq 0x107(%rsp), %rdi
callq 0xb3f0
leaq 0x160(%rsp), %rdi
callq 0x1b3f0
leaq 0x140(%rsp), %rdi
callq 0x97050
jmp 0x5f64e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f5d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f5b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0xb6e8
leaq 0xaf(%rsp), %rdi
callq 0xb3f0
leaq 0xf8(%rsp), %rdi
callq 0x1b3f0
leaq 0xd8(%rsp), %rdi
callq 0x97050
jmp 0x5f64e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f641
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x5f62a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x58(%rsp), %rdi
callq 0xb6e8
leaq 0x57(%rsp), %rdi
callq 0xb3f0
leaq 0xa0(%rsp), %rdi
callq 0x1b3f0
leaq 0x80(%rsp), %rdi
callq 0x97050
movq 0x130(%rsp), %rdi
callq 0xb680
nopl (%rax,%rax)