Skip to content

Commit ee5234e

Browse files
committed
reactor: impl self is strictly limited, &self can only be used after a new request for memory.
1 parent 939ecc6 commit ee5234e

File tree

36 files changed

+159
-649
lines changed

36 files changed

+159
-649
lines changed

nls/src/analyzer/common.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -845,11 +845,6 @@ pub enum ExprOp {
845845
Bnot,
846846
#[strum(to_string = "&")]
847847
La,
848-
#[strum(to_string = "&?")]
849-
SafeLa,
850-
#[strum(to_string = "&!")]
851-
UnsafeLa,
852-
853848
#[strum(to_string = "*")]
854849
Ia,
855850

@@ -923,7 +918,6 @@ pub enum AstNode {
923918

924919
// marco
925920
MacroSizeof(Type), // (target_type)
926-
MacroUla(Box<Expr>), // (src)
927921
MacroReflectHash(Type), // (target_type)
928922
MacroTypeEq(Type, Type), // (left_type, right_type)
929923
MacroAsync(MacroAsyncExpr),

nls/src/analyzer/semantic.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,9 +1384,6 @@ impl<'a> Semantic<'a> {
13841384
AstNode::MacroSizeof(target_type) | AstNode::MacroDefault(target_type) => {
13851385
self.analyze_type(target_type);
13861386
}
1387-
AstNode::MacroUla(src) => {
1388-
self.analyze_expr(src);
1389-
}
13901387
AstNode::MacroReflectHash(target_type) => {
13911388
self.analyze_type(target_type);
13921389
}

nls/src/analyzer/syntax.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,18 +4046,6 @@ impl<'a> Syntax {
40464046
Ok(expr)
40474047
}
40484048

4049-
fn parser_macro_ula_expr(&mut self) -> Result<Box<Expr>, SyntaxError> {
4050-
let mut expr = self.expr_new();
4051-
self.must(TokenType::LeftParen)?;
4052-
4053-
let src = self.parser_expr()?;
4054-
self.must(TokenType::RightParen)?;
4055-
4056-
expr.node = AstNode::MacroUla(src);
4057-
expr.end = self.prev().unwrap().end;
4058-
Ok(expr)
4059-
}
4060-
40614049
fn parser_macro_call(&mut self) -> Result<Box<Expr>, SyntaxError> {
40624050
let token = self.must(TokenType::MacroIdent)?;
40634051

@@ -4067,7 +4055,6 @@ impl<'a> Syntax {
40674055
"reflect_hash" => self.parser_macro_reflect_hash(),
40684056
"default" => self.parser_macro_default_expr(),
40694057
"async" => self.parser_macro_async_expr(),
4070-
"unsafe_load" => self.parser_macro_ula_expr(),
40714058
_ => Err(SyntaxError(token.start, token.end, format!("macro '{}' not defined", token.literal))),
40724059
}
40734060
}

nls/src/analyzer/typesys.rs

Lines changed: 32 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ impl GenericSpecialFnClone {
206206

207207
AstNode::MacroSizeof(target_type) => AstNode::MacroSizeof(target_type.clone()),
208208
AstNode::MacroDefault(target_type) => AstNode::MacroDefault(target_type.clone()),
209-
AstNode::MacroUla(src) => AstNode::MacroUla(Box::new(self.clone_expr(src))),
210209
AstNode::MacroReflectHash(type_) => AstNode::MacroReflectHash(type_.clone()),
211210
AstNode::MacroTypeEq(left, right) => AstNode::MacroTypeEq(left.clone(), right.clone()),
212211

@@ -1636,29 +1635,6 @@ impl<'a> Typesys<'a> {
16361635
return Ok(Type::ptr_of(operand_type));
16371636
}
16381637

1639-
// 处理不安全取地址运算符 @unsafe_la
1640-
if op == ExprOp::UnsafeLa {
1641-
// 检查是否是字面量或函数调用
1642-
if matches!(operand.node, AstNode::Literal(..) | AstNode::Call(..)) {
1643-
return Err(AnalyzerError {
1644-
start: operand.start,
1645-
end: operand.end,
1646-
message: "cannot safe load address of an literal or call".to_string(),
1647-
});
1648-
}
1649-
1650-
// 检查是否是联合类型
1651-
if matches!(operand_type.kind, TypeKind::Union(..)) {
1652-
return Err(AnalyzerError {
1653-
start: operand.start,
1654-
end: operand.end,
1655-
message: "cannot safe load address of an union type".to_string(),
1656-
});
1657-
}
1658-
1659-
return Ok(Type::ptr_of(operand_type));
1660-
}
1661-
16621638
// 处理解引用运算符 *
16631639
if op == ExprOp::Ia {
16641640
// 检查是否是指针类型
@@ -2579,10 +2555,6 @@ impl<'a> Typesys<'a> {
25792555
*target_type = self.reduction_type(target_type.clone())?;
25802556
Ok(Type::new(TypeKind::Int))
25812557
}
2582-
AstNode::MacroUla(src) => {
2583-
let src_type = self.infer_right_expr(src, Type::default())?;
2584-
return Ok(Type::ptr_of(src_type));
2585-
}
25862558
AstNode::New(type_, properties, expr_option) => {
25872559
*type_ = self.reduction_type(type_.clone())?;
25882560

@@ -3578,57 +3550,43 @@ impl<'a> Typesys<'a> {
35783550

35793551
fn self_arg_rewrite(&mut self, type_fn: &TypeFn, self_arg: &mut Expr) -> Result<(), AnalyzerError> {
35803552
let self_param_type = &type_fn.param_types[0];
3581-
let extract_self_type = if matches!(self_param_type.kind, TypeKind::Ref(_) | TypeKind::Ptr(_)) {
3582-
match &self_param_type.kind {
3583-
TypeKind::Ref(value_type) | TypeKind::Ptr(value_type) => value_type.as_ref(),
3584-
_ => unreachable!(),
3585-
}
3586-
} else {
3587-
self_param_type
3588-
};
3589-
3590-
if extract_self_type.is_stack_impl() {
3591-
if matches!(self_param_type.kind, TypeKind::Ref(_)) {
3592-
if matches!(self_arg.type_.kind, TypeKind::Ptr(_)) {
3593-
return Err(AnalyzerError {
3594-
start: self_arg.start,
3595-
end: self_arg.end,
3596-
message: format!("type mismatch: method requires '{}' receiver, got '{}'", self_param_type, self_arg.type_),
3597-
});
3598-
}
3599-
3600-
if !matches!(self_arg.type_.kind, TypeKind::Ref(_)) {
3601-
let mut new_arg = self_arg.clone();
3602-
new_arg.node = AstNode::Unary(ExprOp::SafeLa, Box::new(self_arg.clone()));
3603-
new_arg.type_ = Type::ref_of(self_arg.type_.clone());
3604-
new_arg.target_type = Type::default();
3605-
*self_arg = new_arg;
3606-
}
3607-
} else if matches!(self_param_type.kind, TypeKind::Ptr(_)) {
3608-
if matches!(self_arg.type_.kind, TypeKind::Ptr(_) | TypeKind::Ref(_)) {
3609-
return Ok(());
3610-
}
3611-
3612-
let mut new_arg = self_arg.clone();
3613-
new_arg.node = AstNode::Unary(ExprOp::La, Box::new(self_arg.clone()));
3614-
new_arg.type_ = Type::ptr_of(self_arg.type_.clone());
3615-
*self_arg = new_arg;
3616-
} else {
3617-
if matches!(self_arg.type_.kind, TypeKind::Ptr(_) | TypeKind::Ref(_)) {
3618-
let mut new_arg = self_arg.clone();
3619-
new_arg.node = AstNode::Unary(ExprOp::Ia, Box::new(self_arg.clone()));
3620-
new_arg.type_ = Type::default();
3621-
*self_arg = new_arg;
3622-
}
3623-
}
3624-
} else {
3625-
if !self_arg.type_.is_heap_impl() {
3553+
if matches!(self_param_type.kind, TypeKind::Ref(_)) {
3554+
if matches!(self_arg.type_.kind, TypeKind::Ptr(_)) {
36263555
return Err(AnalyzerError {
36273556
start: self_arg.start,
36283557
end: self_arg.end,
3629-
message: format!("unsupported method receiver type '{}', expected heap-allocated type", self_arg.type_),
3558+
message: format!("type mismatch: method requires '{}' receiver, got '{}'", self_param_type, self_arg.type_),
36303559
});
36313560
}
3561+
3562+
if matches!(self_arg.type_.kind, TypeKind::Ref(_)) || self_arg.type_.is_heap_impl() {
3563+
return Ok(());
3564+
}
3565+
3566+
return Err(AnalyzerError {
3567+
start: self_arg.start,
3568+
end: self_arg.end,
3569+
message: format!("type mismatch: method requires '{}' receiver, got '{}'", self_param_type, self_arg.type_),
3570+
});
3571+
}
3572+
3573+
if matches!(self_param_type.kind, TypeKind::Ptr(_)) {
3574+
if matches!(self_arg.type_.kind, TypeKind::Ptr(_) | TypeKind::Ref(_)) {
3575+
return Ok(());
3576+
}
3577+
3578+
let mut new_arg = self_arg.clone();
3579+
new_arg.node = AstNode::Unary(ExprOp::La, Box::new(self_arg.clone()));
3580+
new_arg.type_ = Type::ptr_of(self_arg.type_.clone());
3581+
*self_arg = new_arg;
3582+
return Ok(());
3583+
}
3584+
3585+
if matches!(self_arg.type_.kind, TypeKind::Ptr(_) | TypeKind::Ref(_)) {
3586+
let mut new_arg = self_arg.clone();
3587+
new_arg.node = AstNode::Unary(ExprOp::Ia, Box::new(self_arg.clone()));
3588+
new_arg.type_ = Type::default();
3589+
*self_arg = new_arg;
36323590
}
36333591

36343592
Ok(())

src/ast.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ typedef enum {
105105
AST_OP_NEG, // unary number -right
106106
AST_OP_BNOT, // unary binary ~right, right must int
107107
AST_OP_LA, // &var = load addr var
108-
AST_OP_SAFE_LA, // @sla(var) safe load addr
109-
AST_OP_UNSAFE_LA, // @ula(var) unsafe load addr
110108
AST_OP_IA, // indirect addr *q
111109

112110
// 位运算
@@ -877,17 +875,6 @@ static inline ast_expr_t *ast_indirect_addr(ast_expr_t *target) {
877875
return result;
878876
}
879877

880-
static inline ast_expr_t *ast_safe_load_addr(ast_expr_t *target) {
881-
ast_expr_t *result = ast_load_addr(target);
882-
ast_unary_expr_t *expr = result->value;
883-
expr->op = AST_OP_SAFE_LA;
884-
result->type.kind = 0;
885-
result->type.status = 0;
886-
result->target_type.kind = 0;
887-
result->target_type.status = 0;
888-
return result;
889-
}
890-
891878
/**
892879
* 已经 infer 过了
893880
* @param expr

src/linear.c

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,66 +2129,20 @@ static lir_operand_t *linear_unary(module_t *m, ast_expr_t expr, lir_operand_t *
21292129
}
21302130

21312131

2132-
if (unary_expr->op == AST_OP_SAFE_LA) {
2133-
assert(!target);
2134-
// target must ptr or anyptr or ptr
2135-
if (!target) {
2136-
target = temp_var_operand(m, type_kind_new(TYPE_ANYPTR));
2137-
}
2138-
2139-
// not need handle analyze? only move? 需要做什么?ident 已经识别出来了。直接 move 到 target 好了
2140-
if (unary_expr->operand.type.storage_kind == STORAGE_KIND_IND || unary_expr->operand.type.kind == TYPE_REF) {
2141-
OP_PUSH(lir_op_move(target, first));
2142-
return target;
2143-
}
2144-
2145-
// 如果 first->assert_type 不是 LIR_OPERAND_INDIRECT_ADDR, 则可能是 call/as/literal 表达式所产生的 var, 此时直接进行堆分配
2146-
if (first->assert_type != LIR_OPERAND_INDIRECT_ADDR) {
2147-
lir_operand_t *temp_operand = temp_var_operand(m, type_refof(unary_expr->operand.type));
2148-
int64_t rtype_hash = type_hash(unary_expr->operand.type);
2149-
push_rt_call(m, RT_CALL_GC_MALLOC, temp_operand, 1, int_operand(rtype_hash));
2150-
lir_operand_t *dst = indirect_addr_operand(m, unary_expr->operand.type, temp_operand, 0);
2151-
OP_PUSH(lir_op_move(dst, first));
2152-
2153-
return temp_operand;
2154-
}
2155-
2156-
2157-
lir_operand_t *src_operand;
2158-
if (first->assert_type == LIR_OPERAND_INDIRECT_ADDR) {
2159-
lir_indirect_addr_t *indirect_addr = first->value;
2160-
if (indirect_addr->offset == 0) {
2161-
// indirect addr base 就是指针本身
2162-
src_operand = indirect_addr->base;
2163-
} else {
2164-
src_operand = lea_operand_pointer(m, first);
2165-
}
2166-
} else {
2167-
src_operand = lea_operand_pointer(m, first);
2168-
}
2169-
2170-
return linear_super_move(m, type_kind_new(TYPE_ANYPTR), target, src_operand);
2171-
}
2172-
21732132
// neg source -> target
21742133
if (!target) {
21752134
target = temp_var_operand_with_alloc(m, expr.type);
21762135
}
21772136

2178-
// &var, 指针引用可能会造成内存逃逸,所以需要特殊处理 TODO 当前版本不存在隐式的逃逸处理,需要显式的调用 sla 才会触发逃逸处理。
2179-
if (unary_expr->op == AST_OP_LA || unary_expr->op == AST_OP_UNSAFE_LA) {
2137+
// &var
2138+
if (unary_expr->op == AST_OP_LA) {
21802139
// 如果是 stack_type, 则直接移动到 target 即可,src 中存放的已经是一个栈指针了,没有必要再 lea 了
21812140
if (unary_expr->operand.type.storage_kind == STORAGE_KIND_IND) {
21822141
// 必须 move target,这同时也是一个类型转换的过程
21832142
OP_PUSH(lir_op_move(target, first));
21842143
return target;
21852144
}
21862145

2187-
if (unary_expr->op == AST_OP_UNSAFE_LA && unary_expr->operand.type.kind == TYPE_REF) {
2188-
OP_PUSH(lir_op_move(target, first));
2189-
return target;
2190-
}
2191-
21922146
// super_move 只有 target == null, 此时直接返回 first
21932147
lir_operand_t *src_operand;
21942148
if (first->assert_type == LIR_OPERAND_INDIRECT_ADDR) {

0 commit comments

Comments
 (0)