Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 714 lines (657 sloc) 34.8 KB
<?php
$(macro) {
declare {
$! // syntax error if no match
$(repeat(either(
chain(
optional(buffer('static') as static),
optional(buffer('inline') as inline),
token(T_FUNCTION),
llvmidentifier() as name,
token('('),
optional(ls(
chain(optional(T_CONST as const), ctype() as type),
token(',')
) as params),
token(')'),
token(':'),
ctype() as returnType,
token(';')
) as func,
chain(
optional(buffer('static') as vararg_static),
optional(buffer('inline') as vararg_inline),
token(T_FUNCTION),
llvmidentifier() as vararg_name,
token('('),
optional(chain(ls(
chain(optional(T_CONST as vararg_const), ctype() as vararg_type),
token(',')
) as vararg_params, token(',')) as vararg_outer_params),
token(T_ELLIPSIS),
token(')'),
token(':'),
ctype() as vararg_returnType,
token(';')
) as vararg_func,
chain(
buffer('struct'),
llvmidentifier() as struct_name,
token('{'),
repeat(
chain(ctype() as field_type, T_VARIABLE as field_name, token(';'))
) as fields,
token('}')
) as struct
)) as decls)
}
} >> {
$(decls ... {
$(func ? ... {
$fntype = $this->context->context->functionType(
$this->context->getTypeFromString($$(stringify($(returnType)))),
false $(params ? { , })
$(params ... ( , ) {
$this->context->getTypeFromString($$(stringify($(type))))
})
);
$fn = $this->context->module->addFunction($$(stringify($(name))), $fntype);
$(inline ? ... {
$fn->addAttributeAtIndex(\PHPLLVM\Attribute::INDEX_FUNCTION, $this->context->attributes['alwaysinline']);
})
$(params ... i {
$(const ? {
$fn->addAttributeAtIndex($(i) + 1, $this->context->attributes['readonly'], 0);
$fn->addAttributeAtIndex($(i) + 1, $this->context->attributes['nocapture'], 0);
})
})
$this->context->registerFunction($$(stringify($(name))), $fn);
})
$(vararg_func ? ... {
$fntype = $this->context->context->functionType(
$this->context->getTypeFromString($$(stringify($(vararg_returnType)))),
true $(vararg_outer_params ... { $(vararg_params ? { , }) })
$(vararg_outer_params ... { $(vararg_params ... ( , ) {
$this->context->getTypeFromString($$(stringify($(vararg_type))))
}) })
);
$fn = $this->context->module->addFunction($$(stringify($(vararg_name))), $fntype);
$(vararg_inline ? ... {
$fn->addAttributeAtIndex(\PHPLLVM\Attribute::INDEX_FUNCTION, $this->context->attributes['alwaysinline']);
})
$(vararg_outer_params ... { $(vararg_params ... i {
$(vararg_const ? {
$fn->addAttributeAtIndex($(i) + 1, $this->context->attributes['readonly'], 0);
$fn->addAttributeAtIndex($(i) + 1, $this->context->attributes['nocapture'], 0);
})
}) })
$this->context->registerFunction($$(stringify($(vararg_name))), $fn);
})
$(struct ? ... {
$struct = $this->context->context->namedStructType($$(stringify($(struct_name))));
// declare first so recursive structs are possible :)
$this->context->registerType($$(stringify($(struct_name))), $struct);
$this->context->registerType($$(stringify($(struct_name))) . '*', $struct->pointerType(0));
$this->context->registerType($$(stringify($(struct_name))) . '**', $struct->pointerType(0)->pointerType(0));
$struct->setBody(
false $(fields ? { , }) // packed
$(fields ... ( , ) {
$this->context->getTypeFromString($$(stringify($(field_type))))
})
);
$this->context->structFieldMap[$$(stringify($(struct_name)))] = [
$(fields ... (, ) i {
$$(stringify($$(unvar($(field_name))))) => $(i)
})
];
})
})
}
$(macro) {
compile {
function $(llvmidentifier() as name) $! ($(optional(ls(
T_VARIABLE as param,
token(',')
)) as params)) {
$(layer() as stmts)
}
}
} >> {
$fn = $this->context->lookupFunction($$(stringify($(name))));
$block = $fn->appendBasicBlock('main');
$this->context->builder->positionAtEnd($block);
$(params ... i {
$(param) = $fn->getParam($(i));
})
compile {
$(stmts)
}
$this->context->builder->clearInsertionPosition();
}
$(macro :unsafe :recursive) {
$(optional(buffer('unsigned')) as unsigned) compile {
$!
$(repeat(either(
chain(T_VARIABLE as result, token('='), either(
chain(T_VARIABLE as nullcheck_var, token(T_IS_EQUAL), buffer('null')) as nullcheck,
chain(T_CONSTANT_ENCAPSED_STRING as conststr_value) as conststr,
chain(either(chain(token('('), ctype() as cast_type, token(')')), T_DOUBLE_CAST as cast_double) as cast_to, expression() as expr) as cast,
chain(T_VARIABLE as field_deref_var, token(T_OBJECT_OPERATOR), label() as field_deref_field) as field_deref,
chain(token('&'), T_VARIABLE as field_deref_ref_var, token(T_OBJECT_OPERATOR), label() as field_deref_ref_field) as field_deref_ref,
chain(T_VARIABLE as field_extract_var, token('.'), label() as field_extract_field) as field_extract,
chain(token('&'), T_VARIABLE as field_extract_ref_var, token('.'), label() as field_extract_ref_field) as field_extract_ref,
chain(T_VARIABLE as gep_load_var, token('['), T_VARIABLE as gep_load_offset, token(']')) as gep_load,
chain(token('&'), T_VARIABLE as gep_var, token('['), T_VARIABLE as gep_offset, token(']')) as gep,
chain(buffer('load'), T_VARIABLE as load_var) as load,
chain(buffer('typeof'), T_VARIABLE as typeof_var) as typeof,
chain(buffer('sizeof'), T_VARIABLE as sizeof_var) as sizeof,
chain(buffer('sizeof'), ctype() as sizeoftype_type) as sizeoftype,
chain(buffer('alloca'), ctype() as alloca_type) as alloca,
chain(buffer('malloc'), ctype() as malloc_type, optional(T_VARIABLE as malloc_extra)) as malloc,
chain(buffer('realloc'), T_VARIABLE as realloc_var, T_VARIABLE as realloc_extra) as realloc,
chain(llvmidentifier() as call_func, token('('), optional(ls(T_VARIABLE as call_arg, token(','))) as call_args, token(')')) as call,
chain(T_VARIABLE as binary_left, either(
token('&') as binary_and,
token('|') as binary_or,
token('^') as binary_xor,
token('+') as binary_add,
token('-') as binary_sub,
token('*') as binary_mul,
token('/') as binary_div,
token('%') as binary_mod,
token('<') as binary_smaller,
token(T_IS_SMALLER_OR_EQUAL) as binary_smaller_equal,
token('>') as binary_greater,
token(T_IS_GREATER_OR_EQUAL) as binary_greater_equal,
token(T_IS_EQUAL) as binary_equals,
token(T_IS_NOT_EQUAL) as binary_not_equal
) as binary_op, either(T_VARIABLE as binary_variable, T_LNUMBER as binary_number) as binary_right) as binary
), token(';')) as assignop,
chain(token(T_RETURN), token(';')) as returnvoid,
chain(token(T_RETURN), T_VARIABLE as returnvalue_value, token(';')) as returnvalue,
chain(T_VARIABLE as inc_result, token(T_INC), token(';')) as inc,
chain(T_VARIABLE as dec_result, token(T_DEC), token(';')) as dec,
chain(token(T_IF), token('('), T_VARIABLE as cond, token(')'), token('{'), layer() as if_stmts, token('}'), optional(chain(token(T_ELSE), token('{'), layer() as else_stmts, token('}')))) as if_stmt,
chain(token(T_SWITCH), T_VARIABLE as switch_cond, token('{'), repeat(chain(token(T_CASE), expression(), token('{'), layer() as switch_case_block, token('}')) as switch_case) as switch_cases, optional(chain(token(T_DEFAULT), token('{'), layer() as switch_default_block, token('}'))), token('}')) as switch_,
chain(T_VARIABLE as field_deref_write_result, token(T_OBJECT_OPERATOR), T_STRING as field_deref_write_field, token('='), T_VARIABLE as field_deref_write_value, token(';')) as field_deref_write,
chain(T_VARIABLE as const_field_assign_var, token('.'), label() as const_field_assign_field, token('='), T_LNUMBER as const_field_assign_value, token(';')) as const_field_assign,
chain(T_VARIABLE as field_assign_var, token('.'), label() as field_assign_field, token('='), T_VARIABLE as field_assign_value, token(';')) as field_assign,
chain(T_VARIABLE as gep_store_var, token('['), T_VARIABLE as gep_store_offset, token(']'), token('='), T_VARIABLE as gep_store_value, token(';')) as gep_store,
chain(buffer('store'), T_VARIABLE as store_value, T_VARIABLE as store_pointer, token(';')) as store,
chain(buffer('dump'), T_VARIABLE as dump_var, token(';')) as dump,
chain(buffer('free'), T_VARIABLE as free_var, token(';')) as free,
chain(buffer('memcpy'), T_VARIABLE as memcpy_dest, T_VARIABLE as memcpy_src, T_VARIABLE as memcpy_length, token(';')) as memcpy,
chain(buffer('memset'), T_VARIABLE as memset_dest, T_LNUMBER as memset_value, T_VARIABLE as memset_length, token(';')) as memset,
chain(llvmidentifier() as voidcall_func, token('('), optional(ls(T_VARIABLE as voidcall_arg, token(',')) as voidcall_args), token(')'), token(';')) as voidcall
)) as stmts)
}
} >> {
$(stmts ... {
$$(trim {
$(assignop ? ... {
$(nullcheck ? ... {
$(result) = $this->context->builder->icmp(\PHPLLVM\Builder::INT_EQ, $(nullcheck_var), $(nullcheck_var)->typeOf()->constNull());
})
$(constle ? ... {
$(result) = $this->context->builder->icmp(
\PHPLLVM\Builder::INT_SLE,
$(constle_left),
$(constle_left)->typeOf()->constInt($(constle_right), false)
);
})
$(conststr ? ... {
$(result) = $this->context->builder->pointerCast(
$this->context->constantFromString($(conststr_value)),
$this->context->getTypeFromString('char*')
);
})
$(cast ? ... {
$(cast_to ... {
$(cast_double ? {
$__type = $this->context->context->doubleType();
})
$(cast_type ? {
$__type = $this->context->getTypeFromString($$(stringify($(cast_type))));
})
})
$__kind = $__type->getKind();
$__value = $(expr);
switch ($__kind) {
case \PHPLLVM\Type::KIND_INTEGER:
if (!is_object($__value)) {
$(result) = $__type->constInt($__value, false);
break;
}
$__other_type = $__value->typeOf();
switch ($__other_type->getKind()) {
case \PHPLLVM\Type::KIND_INTEGER:
if ($__other_type->getWidth() >= $__type->getWidth()) {
$(result) = $this->context->builder->truncOrBitCast($__value, $__type);
} else {
$(result) = $this->context->builder->zExtOrBitCast($__value, $__type);
}
break;
case \PHPLLVM\Type::KIND_DOUBLE:
$(unsigned ? {
$(result) = $this->context->builder->fpToUi($__value, $__type);
})
$(unsigned ! {
$(result) = $this->context->builder->fpToSi($__value, $__type);
})
break;
case \PHPLLVM\Type::KIND_ARRAY:
case \PHPLLVM\Type::KIND_POINTER:
$(result) = $this->context->builder->ptrToInt($__value, $__type);
break;
default:
throw new \LogicException("Unknown how to handle type pair (int, " . $__other_type->toString() . ")");
}
break;
case \PHPLLVM\Type::KIND_DOUBLE:
if (!is_object($__value)) {
$(result) = $__type->constReal($(expr));
break;
}
$__other_type = $__value->typeOf();
switch ($__other_type->getKind()) {
case \PHPLLVM\Type::KIND_INTEGER:
$(unsigned ? {
$(result) = $this->context->builder->uiToFp($__value, $__type);
})
$(unsigned ! {
$(result) = $this->context->builder->siToFp($__value, $__type);
})
break;
case \PHPLLVM\Type::KIND_DOUBLE:
$(result) = $this->context->builder->fpCast($__value, $__type);
break;
default:
throw new \LogicException("Unknown how to handle type pair (double, " . $__other_type->toString() . ")");
}
break;
case \PHPLLVM\Type::KIND_ARRAY:
case \PHPLLVM\Type::KIND_POINTER:
if (!is_object($__value)) {
// this is very likely very wrong...
$(result) = $__type->constInt($__value, false);
break;
}
$__other_type = $__value->typeOf();
switch ($__other_type->getKind()) {
case \PHPLLVM\Type::KIND_INTEGER:
$(result) = $this->context->builder->intToPtr($__value, $__type);
break;
case \PHPLLVM\Type::KIND_ARRAY:
// $__tmp = $this->context->builder->($__value, $this->context->context->int64Type());
// $(result) = $this->context->builder->intToPtr($__tmp, $__type);
// break;
case \PHPLLVM\Type::KIND_POINTER:
$(result) = $this->context->builder->pointerCast($__value, $__type);
break;
default:
throw new \LogicException("Unknown how to handle type pair (double, " . $__other_type->toString() . ")");
}
break;
default:
throw new \LogicException("Unsupported type cast: " . $__type->toString());
}
})
$(load ? ... {
$(result) = $this->context->builder->load($(load_var));
})
$(binary ? ... {
$(binary_op ... {
$(binary_right ... {
$(binary_variable ? {
$__right = $this->context->builder->intCast($(binary_variable), $(binary_left)->typeOf());
})
$(binary_number ? {
$__right = $(binary_left)->typeOf()->constInt($(binary_number), false);
})
})
$(binary_and ? {
$(result) = $this->context->builder->bitwiseAnd($(binary_left), $__right);
})
$(binary_or ? {
$(result) = $this->context->builder->bitwiseOr($(binary_left), $__right);
})
$(binary_xor ? {
$(result) = $this->context->builder->bitwiseXor($(binary_left), $__right);
})
$(binary_add ? {
$(unsigned ? {
$(result) = $this->context->builder->addNoUnsignedWrap($(binary_left), $__right);
})
$(unsigned ! {
$(result) = $this->context->builder->addNoSignedWrap($(binary_left), $__right);
})
})
$(binary_sub ? {
$(unsigned ? {
$(result) = $this->context->builder->subNoUnsignedWrap($(binary_left), $__right);
})
$(unsigned ! {
$(result) = $this->context->builder->subNoSignedWrap($(binary_left), $__right);
})
})
$(binary_mul ? {
$(unsigned ? {
$(result) = $this->context->builder->mulNoUnsignedWrap($(binary_left), $__right);
})
$(unsigned ! {
$(result) = $this->context->builder->mulNoSignedWrap($(binary_left), $__right);
})
})
$(binary_div ? {
$(unsigned ? {
$(result) = $this->context->builder->unsignedDiv($(binary_left), $__right);
})
$(unsigned ! {
$(result) = $this->context->builder->signedDiv($(binary_left), $__right);
})
})
$(binary_mod ? {
$(unsigned ? {
$(result) = $this->context->builder->unsignedRem($(binary_left), $__right);
})
$(unsigned ! {
$(result) = $this->context->builder->signedRem($(binary_left), $__right);
})
})
$(binary_smaller ? {
$(unsigned ? {
$cmp = \PHPLLVM\Builder::INT_ULT;
})
$(unsigned ! {
$cmp = \PHPLLVM\Builder::INT_SLT;
})
$(result) = $this->context->builder->icmp($cmp, $(binary_left), $__right);
})
$(binary_smaller_equal ? {
$(unsigned ? {
$cmp = \PHPLLVM\Builder::INT_ULE;
})
$(unsigned ! {
$cmp = \PHPLLVM\Builder::INT_SLE;
})
$(result) = $this->context->builder->icmp($cmp, $(binary_left), $__right);
})
$(binary_greater ? {
$(unsigned ? {
$cmp = \PHPLLVM\Builder::INT_UGT;
})
$(unsigned ! {
$cmp = \PHPLLVM\Builder::INT_SGT;
})
$(result) = $this->context->builder->icmp($cmp, $(binary_left), $__right);
})
$(binary_greater_equal ? {
$(unsigned ? {
$cmp = \PHPLLVM\Builder::INT_UGE;
})
$(unsigned ! {
$cmp = \PHPLLVM\Builder::INT_SGE;
})
$(result) = $this->context->builder->icmp($cmp, $(binary_left), $__right);
})
$(binary_equals ? {
$(result) = $this->context->builder->icmp(\PHPLLVM\Builder::INT_EQ, $(binary_left), $__right);
})
$(binary_not_equal ? {
$(result) = $this->context->builder->icmp(\PHPLLVM\Builder::INT_NE, $(binary_left), $__right);
})
})
})
$(field_extract ? ... {
$offset = $this->context->structFieldMap[$(field_extract_var)->typeOf()->getName()][$$(stringify($(field_extract_field)))];
$(result) = $this->context->builder->extractValue($(field_extract_var), $offset);
})
$(field_deref ? ... {
$offset = $this->context->structFieldMap[$(field_deref_var)->typeOf()->getElementType()->getName()][$$(stringify($(field_deref_field)))];
$(result) = $this->context->builder->load(
$this->context->builder->structGep($(field_deref_var), $offset)
);
})
$(field_extract_ref ? ... {
$offset = $this->context->structFieldMap[$(field_extract_ref_var)->typeOf()->getName()][$$(stringify($(field_extract_ref_field)))];
$(result) = $this->context->builder->gep(
$(field_extract_ref_var),
$this->context->context->int32Type()->constInt(0, false),
$this->context->context->int32Type()->constInt($offset, false)
);
})
$(field_deref_ref ? ... {
$offset = $this->context->structFieldMap[$(field_deref_ref_var)->typeOf()->getElementType()->getName()][$$(stringify($(field_deref_ref_field)))];
$(result) = $this->context->builder->structGep($(field_deref_ref_var), $offset);
})
$(sizeof ? ... {
if ($(sizeof_var) instanceof \PHPLLVM\Type) {
$type = $(sizeof_var);
} elseif ($(sizeof_var) instanceof \PHPLLVM\Value) {
$type = $(sizeof_var)->typeOf();
} else {
throw new \LogicException("Attempt to call sizeof on non-PHPLLVM type/value");
}
$(result) = $this->context->builder->ptrToInt(
$this->context->builder->gep(
$type->pointerType(0)->constNull(),
$this->context->context->int32Type()->constInt(1, false)
),
$this->context->getTypeFromString('size_t')
);
})
$(typeof ? ... {
if ($(typeof_var) instanceof \PHPLLVM\Type) {
$(result) = $(typeof_var);
} elseif ($(typeof_var) instanceof \PHPLLVM\Value) {
$(result) = $(typeof_var)->typeOf();
} else {
throw new \LogicException("Attempt to call typeof on non-PHPLLVM type/value");
}
})
$(sizeoftype ? ... {
$type = $this->context->getTypeFromString($$(stringify($(sizeoftype_type))));
$(result) = $this->context->builder->ptrToInt(
$this->context->builder->gep(
$type->pointerType(0)->constNull(),
$this->context->context->int32Type()->constInt(1, false)
),
$this->context->getTypeFromString('size_t')
);
})
$(gep ? ... {
$(result) = $this->context->builder->gep(
$(gep_var),
//$this->context->context->int32Type()->constInt(0, false),
//$this->context->context->int32Type()->constInt(0, false),
$(gep_offset)
);
})
$(gep_load ? ... {
$(result) = $this->context->builder->load($this->context->builder->gep(
$(gep_load_var),
//$this->context->context->int32Type()->constInt(0, false),
//$this->context->context->int32Type()->constInt(0, false),
$(gep_load_offset)
));
})
$(malloc ? ... {
$type = $this->context->getTypeFromString($$(stringify($(malloc_type))));
$(malloc_extra ? {
$(result) = $this->context->memory->mallocWithExtra($type, $(malloc_extra));
})
$(malloc_extra ! {
$(result) = $this->context->memory->malloc($type);
})
})
$(alloca ? ... {
$type = $this->context->getTypeFromString($$(stringify($(alloca_type))));
$(result) = $this->context->builder->alloca($type);
})
$(realloc ? ... {
$(result) = $this->context->memory->realloc($(realloc_var), $(realloc_extra));
})
$(call ? ... {
$(result) = $this->context->builder->call(
$this->context->lookupFunction($$(stringify($(call_func)))) $(call_args ? {, })
$(call_args ... (, ) {
$(call_arg)
})
);
})
})
$(returnvoid ? {
$this->context->builder->returnVoid();
})
$(returnvalue ? ... {
$this->context->builder->returnValue($(returnvalue_value));
})
$(inc ? ... {
$(inc_result) = $this->context->builder->add($(inc_result), $(inc_result)->typeOf()->constInt(1, false));
})
$(dec ? ... {
$(dec_result) = $this->context->builder->sub($(dec_result), $(dec_result)->typeOf()->constInt(1, false));
})
$(switch_ ? ... {
$__switches[] = $__switch = new \StdClass;
$__switch->type = $(switch_cond)->typeOf();
$__prev = $this->context->builder->getInsertBlock();
$__switch->default = $__prev->insertBasicBlock('default');
$__prev->moveBefore($__switch->default);
$__switch->end = $__switch->default->insertBasicBlock('end');
$__switch->endIsUsed = false;
$__switch->numCases = 0;
$(switch_cases ... {
$__switch->numCases++;
})
$__switch->switch = $this->context->builder->branchSwitch($(switch_cond), $__switch->default, $__switch->numCases);
$(switch_cases ... { $(switch_case ... i {
$__case = end($__switches)->default->insertBasicBlock('case_' . $(i));
$this->context->builder->positionAtEnd($__case);
if (is_int($(expr))) {
end($__switches)->switch->addCase(end($__switches)->type->constInt($(expr), false), $__case);
} elseif ($(expr) instanceof \PHPLLVM\Value) {
end($__switches)->switch->addCase($(expr), $__case);
} else {
throw new \LogicException("Unknown type for switch case");
}
$$(expand( { $(unsigned) compile {
$(switch_case_block)
} }))
if ($this->context->builder->getInsertBlock()->getTerminator() === null) {
$this->context->builder->branch(end($__switches)->end);
end($__switches)->endIsUsed = true;
}
})})
$this->context->builder->positionAtEnd(end($__switches)->default);
$(switch_default_block ? {
$$(expand( { compile {
$(switch_default_block)
} }))
})
if ($this->context->builder->getInsertBlock()->getTerminator() === null) {
$this->context->builder->branch(end($__switches)->end);
end($__switches)->endIsUsed = true;
}
$__switch = array_pop($__switches);
if ($__switch->endIsUsed) {
$this->context->builder->positionAtEnd($__switch->end);
} else {
$__switch->end->remove();
}
})
$(if_stmt ? ... {
$bool = $this->context->castToBool($(cond));
$prev = $this->context->builder->getInsertBlock();
$ifBlock = $prev->insertBasicBlock('ifBlock');
$prev->moveBefore($ifBlock);
$(else_stmts ? {
$elseBlock[] = $tmp = $ifBlock->insertBasicBlock('elseBlock');
$endBlock[] = $ifBlock->insertBasicBlock('endBlock');
$this->context->builder->branchIf($bool, $ifBlock, $tmp);
})
$(else_stmts ! {
$endBlock[] = $tmp = $ifBlock->insertBasicBlock('endBlock');
$this->context->builder->branchIf($bool, $ifBlock, $tmp);
})
$this->context->builder->positionAtEnd($ifBlock);
$$(expand( { compile {
$(if_stmts)
}}))
if ($this->context->builder->getInsertBlock()->getTerminator() === null) {
$this->context->builder->branch(end($endBlock));
}
$(else_stmts ? {
$this->context->builder->positionAtEnd(array_pop($elseBlock));
$$(expand( { compile {
$(else_stmts)
}}))
if ($this->context->builder->getInsertBlock()->getTerminator() === null) {
$this->context->builder->branch(end($endBlock));
}
})
$this->context->builder->positionAtEnd(array_pop($endBlock));
})
$(field_deref_write ? ... {
$offset = $this->context->structFieldMap[$(field_deref_write_result)->typeOf()->getElementType()->getName()][$$(stringify($(field_deref_write_field)))];
$this->context->builder->store(
$(field_deref_write_value),
$this->context->builder->structGep($(field_deref_write_result), $offset)
);
})
$(field_assign ? ... {
$offset = $this->context->structFieldMap[$(field_assign_var)->typeOf()->getName()][$$(stringify($(field_assign_field)))];
$this->context->builder->insertValue(
$(field_assign_var),
$(field_assign_value),
$offset
);
})
$(const_field_assign ? ... {
$structType = $(const_field_assign_var)->typeOf();
$offset = $this->context->structFieldMap[$structType->getName()][$$(stringify($(const_field_assign_field)))];
$this->context->builder->insertValue(
$(const_field_assign_var),
$structType->getElementAtIndex($offset)->constInt($(const_field_assign_value), false),
$offset
);
})
$(memcpy ? ... {
$this->context->intrinsic->memcpy($(memcpy_dest), $(memcpy_src), $(memcpy_length), false);
})
$(memset ? ... {
$this->context->intrinsic->memset(
$(memset_dest),
$this->context->context->int8Type()->constInt($(memset_value), false),
$(memset_length),
false
);
})
$(store ? ... {
$this->context->builder->store($(store_value), $(store_pointer));
})
$(gep_store ? ... {
$this->context->builder->store($(gep_store_value), $this->context->builder->gep(
$(gep_store_var),
//$this->context->context->int32Type()->constInt(0, false),
//$this->context->context->int32Type()->constInt(0, false),
$(gep_store_offset)
));
})
$(free ? ... {
$this->context->memory->free($(free_var));
})
$(dump ? ... {
$(dump_var)->dump();
})
$(voidcall ? ... {
$this->context->builder->call(
$this->context->lookupFunction($$(stringify($(voidcall_func)))) $(voidcall_args ? {, })
$(voidcall_args ... (, ) {
$(voidcall_arg)
})
);
})
})
})
}
You can’t perform that action at this time.