mt-lang 0.2.19 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 98c4dc25b7d1fb3ab4931eed5fd30c29e30448a3b2c3fe85d6b58d823fab7baa
|
|
4
|
+
data.tar.gz: a025a925117c16e69f85667f4411a5d09b92ac0ea65e6ec061111578db39001a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e18ef0444a502981b66eed892a94ccc92918c2d1254669d912e27a8e43b552d360cbc9d4eaf386935b141700ee992eedb365093c00bd67e35e3d878e20f17fbb
|
|
7
|
+
data.tar.gz: 1e642ded750895e1cabc818bff33c7a88beffc463975d46dc98a2a45cb7eb07d53ee57580fee90fd31b3d8af011e4477a41779044c535513a444457bcd12a902
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -450,6 +450,21 @@ module MilkTea
|
|
|
450
450
|
raise_sema_error("safe array indexing requires an addressable array value; bind it to a local first")
|
|
451
451
|
end
|
|
452
452
|
|
|
453
|
+
if array_type?(receiver_type) && expression.index.is_a?(AST::IntegerLiteral)
|
|
454
|
+
length = array_length(receiver_type)
|
|
455
|
+
index_val = expression.index.value
|
|
456
|
+
if index_val >= length || index_val < 0
|
|
457
|
+
raise_sema_error("array index #{index_val} is out of bounds for array[T, #{length}]", expression)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
if array_type?(receiver_type) && expression.index.is_a?(AST::UnaryOp) && expression.index.operator == "-" &&
|
|
462
|
+
expression.index.operand.is_a?(AST::IntegerLiteral)
|
|
463
|
+
length = array_length(receiver_type)
|
|
464
|
+
index_val = -expression.index.operand.value
|
|
465
|
+
raise_sema_error("array index #{index_val} is out of bounds for array[T, #{length}]", expression)
|
|
466
|
+
end
|
|
467
|
+
|
|
453
468
|
infer_index_result_type(receiver_type, index_type)
|
|
454
469
|
end
|
|
455
470
|
|
|
@@ -185,6 +185,7 @@ module MilkTea
|
|
|
185
185
|
|
|
186
186
|
validate_consuming_foreign_expression!(statement.value, scopes:, root_allowed: false) if statement.value
|
|
187
187
|
value_type = statement.value ? infer_expression(statement.value, scopes:, expected_type: return_type) : @ctx.types.fetch("void")
|
|
188
|
+
check_stack_pointer_escape_in_return(statement.value, scopes:) if statement.value
|
|
188
189
|
ensure_assignable!(
|
|
189
190
|
value_type,
|
|
190
191
|
return_type,
|
|
@@ -1322,6 +1323,64 @@ module MilkTea
|
|
|
1322
1323
|
end
|
|
1323
1324
|
end
|
|
1324
1325
|
|
|
1326
|
+
# Walks the returned expression tree to detect ptr_of/ref_of/const_ptr_of
|
|
1327
|
+
# applied to a stack-local variable whose address must not escape the
|
|
1328
|
+
# function. Only flags when the pointer value itself (not a computed
|
|
1329
|
+
# result through a function call) reaches the return.
|
|
1330
|
+
def check_stack_pointer_escape_in_return(expression, scopes:)
|
|
1331
|
+
return unless expression
|
|
1332
|
+
|
|
1333
|
+
if expression.is_a?(AST::Call)
|
|
1334
|
+
check_stack_escape_call(expression, scopes:)
|
|
1335
|
+
elsif expression.is_a?(AST::BinaryOp)
|
|
1336
|
+
check_stack_pointer_escape_in_return(expression.left, scopes:)
|
|
1337
|
+
check_stack_pointer_escape_in_return(expression.right, scopes:)
|
|
1338
|
+
elsif expression.is_a?(AST::UnaryOp)
|
|
1339
|
+
check_stack_pointer_escape_in_return(expression.operand, scopes:)
|
|
1340
|
+
end
|
|
1341
|
+
end
|
|
1342
|
+
|
|
1343
|
+
def check_stack_escape_call(expression, scopes:)
|
|
1344
|
+
callee = expression.callee
|
|
1345
|
+
return unless callee.is_a?(AST::Identifier)
|
|
1346
|
+
return unless %w[ptr_of ref_of const_ptr_of].include?(callee.name)
|
|
1347
|
+
return if expression.arguments.empty?
|
|
1348
|
+
|
|
1349
|
+
arg = expression.arguments.first
|
|
1350
|
+
source = arg.respond_to?(:value) ? arg.value : arg
|
|
1351
|
+
check_stack_local_source(source, scopes:, builtin: callee.name)
|
|
1352
|
+
end
|
|
1353
|
+
|
|
1354
|
+
def check_stack_local_source(expression, scopes:, builtin:)
|
|
1355
|
+
case expression
|
|
1356
|
+
when AST::Identifier
|
|
1357
|
+
binding = lookup_local_binding(expression.name, scopes)
|
|
1358
|
+
return unless binding
|
|
1359
|
+
return unless %i[let var param].include?(binding.kind)
|
|
1360
|
+
return if stack_safe_pointer_source?(binding)
|
|
1361
|
+
raise_sema_error(
|
|
1362
|
+
"#{builtin}(#{expression.name}) cannot be returned: pointer to function-local storage",
|
|
1363
|
+
expression,
|
|
1364
|
+
)
|
|
1365
|
+
when AST::MemberAccess
|
|
1366
|
+
check_stack_local_source(expression.receiver, scopes:, builtin:)
|
|
1367
|
+
when AST::IndexAccess
|
|
1368
|
+
check_stack_local_source(expression.receiver, scopes:, builtin:)
|
|
1369
|
+
end
|
|
1370
|
+
end
|
|
1371
|
+
|
|
1372
|
+
def lookup_local_binding(name, scopes)
|
|
1373
|
+
scopes.reverse_each do |scope|
|
|
1374
|
+
return scope[name] if scope.key?(name)
|
|
1375
|
+
end
|
|
1376
|
+
nil
|
|
1377
|
+
end
|
|
1378
|
+
|
|
1379
|
+
def stack_safe_pointer_source?(binding)
|
|
1380
|
+
return false unless binding.type
|
|
1381
|
+
ref_type?(binding.type) || own_type?(binding.type)
|
|
1382
|
+
end
|
|
1383
|
+
|
|
1325
1384
|
end
|
|
1326
1385
|
end
|
|
1327
1386
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mt-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -586,7 +586,7 @@ metadata:
|
|
|
586
586
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
587
587
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
588
588
|
post_install_message: |
|
|
589
|
-
Milk Tea 0.2.
|
|
589
|
+
Milk Tea 0.2.20 installed!
|
|
590
590
|
|
|
591
591
|
System requirements:
|
|
592
592
|
- A C compiler (gcc or clang) must be available on PATH
|