From b04d90df22c68e4f3d4c2bd6afebd21949c07499 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Mon, 9 Dec 2024 14:13:46 -0800 Subject: [PATCH 1/3] WIP: unsafe table lookups --- daslib/json.das | 2 +- daslib/macro_boost.das | 3 +- daslib/templates_boost.das | 64 +-- .../test/compilation_fail_tests/const_ref.das | 4 +- examples/test/optimizations/array_r2v.das | 19 +- examples/test/unit_tests/clone.das | 6 +- examples/test/unit_tests/new_delete.das | 4 +- examples/test/unit_tests/safe_index.das | 8 +- examples/test/unit_tests/table.das | 28 +- .../test/unit_tests/test_value_table_key.das | 6 +- examples/test/unit_tests/totable.das | 2 +- include/daScript/ast/ast.h | 1 + .../daScript/simulate/runtime_table_nodes.h | 1 + src/ast/ast_infer_type.cpp | 21 + src/ast/ast_lint.cpp | 1 + src/builtin/builtin.das | 79 +++- src/builtin/builtin.das.inc | 390 +++++++++++++++++- src/builtin/module_builtin_rtti.cpp | 1 + 18 files changed, 543 insertions(+), 97 deletions(-) diff --git a/daslib/json.das b/daslib/json.das index 756be7058..f592a1518 100644 --- a/daslib/json.das +++ b/daslib/json.das @@ -246,7 +246,7 @@ def private parse_value ( var itv : iterator; var error : string & ) : if !allow_duplicate_keys && key_exists(tab,key) error = "duplicate key {key} at {ahead.line}:{ahead.row}" return null - tab[key] = value + tab |> insert(key,value) if !expect_token(itv, ahead, Token_symbol, error) return null let sepsym = ahead.value as _symbol diff --git a/daslib/macro_boost.das b/daslib/macro_boost.das index 695be4e4c..fd019b135 100644 --- a/daslib/macro_boost.das +++ b/daslib/macro_boost.das @@ -39,7 +39,8 @@ class CaptureBlock : AstVisitor return let vptr = get_ptr(expr.variable) if !(scope |> key_exists(vptr)) - captured[vptr] = unsafe(reinterpret get_ptr(expr)) + unsafe + captured[vptr] = reinterpret get_ptr(expr) def override preVisitExprLetVariable(expr:smart_ptr;arg:VariablePtr;lastArg:bool) : void scope |> insert(get_ptr(arg)) def override preVisitExprForVariable(expr:smart_ptr;svar:VariablePtr;last:bool) : void diff --git a/daslib/templates_boost.das b/daslib/templates_boost.das index 6c8eaad3f..1be4ba623 100644 --- a/daslib/templates_boost.das +++ b/daslib/templates_boost.das @@ -28,15 +28,15 @@ struct Template def kaboomVarField ( var self:Template; name,prefix,suffix:string ) //! Adds a rule to to the template to replace a variable field access with a prefix and suffix. //! I.e. foo.bar into prefix + bar + suffix - self.kaboomVar[name] = [[auto prefix,suffix]] + self.kaboomVar |> emplace(name, [[auto prefix,suffix]]) def replaceVariable ( var self:Template; name:string; var expr : smart_ptr ) //! Adds a rule to the template to replace a variable with an expression. - move(self.var2expr[name], expr) + self.var2expr |> emplace(name, expr) def replaceVarTag ( var self:Template; name:string; var expr : smart_ptr ) //! Adds a rule to the template to replace a variable tag with an expression. - move(self.tag2expr[name], expr) + self.tag2expr |> emplace(name, expr) def replaceArgumentWithList ( var self:Template; name:string; blka:array ) //! Adds a rule to the template to replace a block argument with a list of variables. @@ -55,43 +55,43 @@ def replaceVariableWithList ( var self:Template; name:string; expr : dasvector`s def renameVariable ( var self:Template; name, newName:string ) //! Adds a rule to the template to rename a variable. - self.var2name[name] = newName + self.var2name |> insert(name, newName) def renameVariable ( var self:Template; name:string; newName:das_string ) //! Adds a rule to the template to rename a variable. - self.var2name[name] = string(newName) + self.var2name |> insert(name, string(newName)) def renameField ( var self:Template; name, newName:string ) //! Adds a rule to the template to rename any field lookup (., ?., as, is, etc) - self.field2name[name] = newName + self.field2name |> insert(name, newName) def renameField ( var self:Template; name:string; newName:das_string ) //! Adds a rule to the template to rename any field lookup (., ?., as, is, etc) - self.field2name[name] = string(newName) + self.field2name |> insert(name, string(newName)) def replaceType ( var self:Template; name,newName:string ) //! Adds a rule to the template to replace a type alias with another type alias, specified by name. - self.type2type[name] = newName + self.type2type |> insert(name, newName) def replaceTypeWithTypeDecl ( var self:Template; name:string; var expr : TypeDeclPtr ) //! Adds a rule to the template to replace a type alias with another type alias, specified by type declaration. - move(self.type2etype[name], expr) + self.type2etype |> emplace(name, expr) def replaceAnnotationArgument ( var self:Template; name:string; var cb:lambda<(var ann: AnnotationDeclaration):void> ) //! Adds a rule to the template to replace an annotation argument with the result of a callback. - self.annArg[name] <- cb + self.annArg |> emplace(name, cb) def replaceBlockArgument ( var self:Template; name,newName:string ) //! Adds a rule to the template to rename a block argument. - self.blockArgName[name] = newName + self.blockArgName |> insert(name, newName) def renameCall ( var self:Template; name, newName:string ) //! Adds a rule to the template to rename a call. - self.call2name[name] = newName + self.call2name |> insert(name, newName) def renameCall ( var self:Template; name:string; newName:das_string ) //! Adds a rule to the template to rename a call. - self.call2name[name] = string(newName) + self.call2name |> insert(name, string(newName)) class private TemplateVisitor : AstVisitor [[do_not_delete]] rules : Template? @@ -102,38 +102,38 @@ class private TemplateVisitor : AstVisitor if expr.subexpr is ExprVar let tn = string((expr.subexpr as ExprVar).name) if key_exists(rules.tag2expr, tn) - var inscope rexpr <- clone_expression(rules.tag2expr[tn]) + var inscope rexpr <- clone_expression(unsafe(rules.tag2expr[tn])) rexpr.at = expr.at return <- rexpr return <- expr def override preVisitExprMakeStructField(expr:smart_ptr;index:int;var decl:MakeFieldDeclPtr;last:bool) : void let fname = string(decl.name) if rules.field2name |> key_exists(fname) - decl.name := rules.field2name[fname] + decl.name := rules.field2name |> get_value(fname) def override visitExprIsVariant(var expr:smart_ptr) : ExpressionPtr let fname = string(expr.name) if rules.field2name |> key_exists(fname) - expr.name := rules.field2name[fname] + expr.name := rules.field2name |> get_value(fname) return <- expr def override visitExprAsVariant(var expr:smart_ptr) : ExpressionPtr let fname = string(expr.name) if rules.field2name |> key_exists(fname) - expr.name := rules.field2name[fname] + expr.name := rules.field2name |> get_value(fname) return <- expr def override visitExprSafeAsVariant(var expr:smart_ptr) : ExpressionPtr let fname = string(expr.name) if rules.field2name |> key_exists(fname) - expr.name := rules.field2name[fname] + expr.name := rules.field2name |> get_value(fname) return <- expr def override visitExprSafeField(var expr:smart_ptr) : ExpressionPtr let fname = string(expr.name) if rules.field2name |> key_exists(fname) - expr.name := rules.field2name[fname] + expr.name := rules.field2name |> get_value(fname) return <- expr def override visitExprField(var expr:smart_ptr) : ExpressionPtr let fname = string(expr.name) if rules.field2name |> key_exists(fname) - expr.name := rules.field2name[fname] + expr.name := rules.field2name |> get_value(fname) var ev = expr.value ?as ExprVar if ev == null ev = (expr.value ?as ExprRef2Value) ?as ExprVar @@ -146,20 +146,20 @@ class private TemplateVisitor : AstVisitor def override visitExprAddr( var expr:smart_ptr ) : ExpressionPtr let vn = string(expr.target) if key_exists(rules.var2name,vn) - expr.target := rules.var2name[vn] + expr.target := rules.var2name |> get_value(vn) return <- expr def override visitExprLet( var expr:smart_ptr ) : ExpressionPtr for v in expr.variables let vn = string(v.name) if key_exists(rules.var2name,vn) - v.name := rules.var2name[vn] + v.name := rules.var2name |> get_value(vn) return <- expr def override visitExprVar(var expr:smart_ptr) : ExpressionPtr let vn = string(expr.name) if key_exists(rules.var2name,vn) - expr.name := rules.var2name[vn] + expr.name := rules.var2name |> get_value(vn) if key_exists(rules.var2expr,vn) - var inscope rexpr <- clone_expression(rules.var2expr[vn]) + var inscope rexpr <- clone_expression(unsafe(rules.var2expr[vn])) rexpr.at = expr.at return <- rexpr return <- expr @@ -167,9 +167,9 @@ class private TemplateVisitor : AstVisitor if typ.baseType==Type alias let ta = string(typ.alias) if key_exists(rules.type2etype, ta) - move_new(typ) <| clone_type(rules.type2etype[ta]) + move_new(typ) <| clone_type(unsafe(rules.type2etype[ta])) elif key_exists(rules.type2type, ta) - typ.alias := rules.type2type[ta] + typ.alias := rules.type2type |> get_value(ta) if typ.firstType != null self->replaceAlias(typ.firstType) if typ.secondType != null @@ -184,14 +184,14 @@ class private TemplateVisitor : AstVisitor for it in expr.iterators let itn = string(it) if key_exists(rules.var2name,itn) - it := rules.var2name[itn] + it := rules.var2name |> get_value(itn) def override preVisitExprBlock(var blk:smart_ptr) if !blk.blockFlags.isClosure return for arg in blk.arguments let vn = "{arg.name}" if key_exists(rules.blockArgName, vn) - arg.name := rules.blockArgName[vn] + arg.name := rules.blockArgName |> get_value(vn) for ann in blk.annotations rules.annArg |> get("{ann.annotation.name}") <| $(cb) cb |> invoke(*ann) @@ -214,7 +214,7 @@ class private TemplateVisitor : AstVisitor for na in new_args blk.arguments |> emplace(na, rai) elif key_exists(rules.var2name, vname) - arg.name := rules.var2name[vname] + arg.name := rules.var2name |> get_value(vname) def preVisitAnythingCall(var arguments:dasvector`smart_ptr`Expression) : void if length(rules.var2exprList)==0 return @@ -237,17 +237,17 @@ class private TemplateVisitor : AstVisitor def override preVisitExprLooksLikeCall(var expr:smart_ptr): void let cname = string(expr.name) if rules.call2name |> key_exists(cname) - expr.name := rules.call2name[cname] + expr.name := rules.call2name |> get_value(cname) preVisitAnythingCall(expr.arguments) def override preVisitExprCall(var expr:smart_ptr): void let cname = string(expr.name) if rules.call2name |> key_exists(cname) - expr.name := rules.call2name[cname] + expr.name := rules.call2name |> get_value(cname) preVisitAnythingCall(expr.arguments) def override preVisitExprAddr(var expr:smart_ptr): void let cname = string(expr.target) if rules.call2name |> key_exists(cname) - expr.target := rules.call2name[cname] + expr.target := rules.call2name |> get_value(cname) def override preVisitExprMakeArray(var expr:smart_ptr): void preVisitAnythingCall(expr.values) diff --git a/examples/test/compilation_fail_tests/const_ref.das b/examples/test/compilation_fail_tests/const_ref.das index d3d7f7ec8..0962a39de 100644 --- a/examples/test/compilation_fail_tests/const_ref.das +++ b/examples/test/compilation_fail_tests/const_ref.das @@ -64,8 +64,8 @@ def test if true var a:table var b:table const - a["key"]++ - b["key"]++ // 30106: can't index in the constant table, use find instead + unsafe(a["key"])++ + unsafe(b["key"])++ // 30106: can't index in the constant table, use find instead if true var a:int? var b:int const? diff --git a/examples/test/optimizations/array_r2v.das b/examples/test/optimizations/array_r2v.das index 62b798c5e..5588788d4 100644 --- a/examples/test/optimizations/array_r2v.das +++ b/examples/test/optimizations/array_r2v.das @@ -4,15 +4,16 @@ struct Foo x,y,z,w:int def testA(var a) - for x in range(10) - a[x].y = x - a[3].z = 13 - for x in range(10) - if x!=3 - assert(a[x].x==0 && a[x].y==x && a[x].z==0 && a[x].w==0) - else - assert(a[x].x==0 && a[x].y==x && a[x].z==13 && a[x].w==0) - assert(a[3].z==13) + unsafe + for x in range(10) + a[x].y = x + a[3].z = 13 + for x in range(10) + if x!=3 + assert(a[x].x==0 && a[x].y==x && a[x].z==0 && a[x].w==0) + else + assert(a[x].x==0 && a[x].y==x && a[x].z==13 && a[x].w==0) + assert(a[3].z==13) [export] def test diff --git a/examples/test/unit_tests/clone.das b/examples/test/unit_tests/clone.das index 83b685de6..937dd3efc 100644 --- a/examples/test/unit_tests/clone.das +++ b/examples/test/unit_tests/clone.das @@ -62,13 +62,13 @@ def test_clone_array def test_clone_table var x, y : table for t in range(3) - x[t] = string(t) + x |> insert(t, string(t)) y := x for t in range(3) - x[t] = string(t+1) + x |> insert(t, string(t+1)) assert(length(y)==3) for t in range(3) - verify(y[t]==string(t)) + verify(y |> get_value(t)==string(t)) [export] def test diff --git a/examples/test/unit_tests/new_delete.das b/examples/test/unit_tests/new_delete.das index 78aa7d1f0..ce353d361 100644 --- a/examples/test/unit_tests/new_delete.das +++ b/examples/test/unit_tests/new_delete.das @@ -24,8 +24,8 @@ def test_delete_array def test_delete_table var a : table let w0 = heap_bytes_allocated() - a[0] = 1 - a[1] = 2 + a |> insert(0,1) + a |> insert(1,2) let w1 = heap_bytes_allocated() delete a let w2 = heap_bytes_allocated() diff --git a/examples/test/unit_tests/safe_index.das b/examples/test/unit_tests/safe_index.das index 7e7aaed2e..30aafb97e 100644 --- a/examples/test/unit_tests/safe_index.das +++ b/examples/test/unit_tests/safe_index.das @@ -35,9 +35,9 @@ def test() dummy = 0 ta?["one"] ?? dummy = 1 assert(dummy==1) - ta["one"] = 0 + ta |> insert("one",0 ) ta?["one"] ?? dummy = 2 - verify(length(ta)==1 && ta["one"]==2) + verify(length(ta)==1 && ta |> get_value("one")==2) assert(dummy==1) var pta = safe_addr(ta) @@ -46,9 +46,9 @@ def test() pta?["one"] ?? dummy = 1 assert(dummy==1) assert(length(ta)==0) - ta["one"] = 1 + ta |> insert("one",1) pta?["one"] ?? dummy = 2 - verify(length(ta)==1 && ta["one"]==2) + verify(length(ta)==1 && ta |> get_value("one")==2) assert(dummy==1) pta = null pta?["one"] ?? dummy = 3 diff --git a/examples/test/unit_tests/table.das b/examples/test/unit_tests/table.das index 7a638f110..8ec77e21d 100644 --- a/examples/test/unit_tests/table.das +++ b/examples/test/unit_tests/table.das @@ -40,13 +40,13 @@ def test : bool i = 0 while i!=total // tab[string(i)] = i++ - tab[string(i)] = i + tab |> insert(string(i),i) i++ assert(length(tab)==total) // debug(tab) i = 0 while i!=total - verify(tab[string(i)]==i) + verify(tab |>get_value(string(i))==i) i++ assert(length(tab)==total) // debug(tab) @@ -99,13 +99,13 @@ def test : bool // debug(tab) i = 0 while i < total - tab[string(i)] = i + tab|>insert(string(i),i) i += 7 assert(length(tab)==total) // debug(tab) i = 0 while i!=total - verify(tab[string(i)]==i) + verify(tab |> get_value(string(i))==i) i++ assert(length(tab)==total) // debug(tab) @@ -123,32 +123,32 @@ def test : bool var tab_bool:table assert(!key_exists(tab_bool, false)) assert(!key_exists(tab_bool, true)) - tab_bool[true] = 0 + tab_bool |> insert(true,0) assert(key_exists(tab_bool, true)) - tab_bool[false] = -1 + tab_bool |> insert(false,-1) assert(key_exists(tab_bool, false)) var tab_int:table assert(!key_exists(tab_int, -1)) - tab_int[-1] = -1 + tab_int |> insert(-1,-1) assert(key_exists(tab_int, -1)) erase(tab_int, -1) assert(!key_exists(tab_int, -1)) var tab_string:table assert(!key_exists(tab_string, "---")) - tab_string["---"] = -1 + tab_string |> insert("---",-1) assert(key_exists(tab_string, "---")) erase(tab_string, "---") assert(!key_exists(tab_string, "---")) assert(!key_exists(tab_string, " ")) - tab_string[" "] = -1 + tab_string |> insert(" ",-1) assert(key_exists(tab_string, " ")) erase(tab_string, " ") assert(!key_exists(tab_string, " ")) - tab_string[""] = -2 + tab_string |> insert("",-2) assert(key_exists(tab_string, "")) - verify(tab_string[""] == -2) + verify(tab_string |> get_value("") == -2) erase(tab_string, "") assert(!key_exists(tab_string, "")) @@ -164,7 +164,7 @@ def test_lock_panic try find(tab,"one") <| $(t) assert(t!=null) - tab["three"] = 3 + tab |> insert("three",3) recover failed = true assert(failed) @@ -197,7 +197,7 @@ def check(var t : TableContainer; deletedEntries : array) if deleted continue let n = "name_{i}" - if t.t[n].test != n + if t.t |> get_value(n).test != n return false return true @@ -208,7 +208,7 @@ def test_erase_collision for i in range(1, TOTAL) push(names, "name_{i}") for n in names - t.t[n] <- [[TestStruct test = n ]] + t.t |> emplace(n,[[TestStruct test = n ]]) var deletedEntries : array verify(check(t, deletedEntries)) for i in range(1, TOTAL) diff --git a/examples/test/unit_tests/test_value_table_key.das b/examples/test/unit_tests/test_value_table_key.das index f598f8850..5b745e3a4 100644 --- a/examples/test/unit_tests/test_value_table_key.das +++ b/examples/test/unit_tests/test_value_table_key.das @@ -3,9 +3,9 @@ require UnitTest [export] def test var tab : table - tab[EntityId(1)] = "hello" - tab[EntityId(2)] = "world" - tab[EntityId(3)] = "!" + tab |> insert(EntityId(1), "hello") + tab |> insert(EntityId(2), "world") + tab |> insert(EntityId(3), "!") assert(length(tab) == 3) tab |> erase(EntityId(3)) assert(length(tab) == 2) diff --git a/examples/test/unit_tests/totable.das b/examples/test/unit_tests/totable.das index dd846c4a3..df546b69c 100644 --- a/examples/test/unit_tests/totable.das +++ b/examples/test/unit_tests/totable.das @@ -3,6 +3,6 @@ def test let a = [[ auto 1 => "one"; 2 => "two"; 3 => "three" ]] var b <- to_table([[ auto 1 => "one"; 2 => "two"; 3 => "three" ]]) for t in a - verify(b[t._0]==t._1) + verify(b |> get_value(t._0)==t._1) return true diff --git a/include/daScript/ast/ast.h b/include/daScript/ast/ast.h index 73627a324..29a3b2bab 100644 --- a/include/daScript/ast/ast.h +++ b/include/daScript/ast/ast.h @@ -1421,6 +1421,7 @@ namespace das // rtti bool rtti = false; // create extended RTTI // language + bool unsafe_table_lookup = false; // table lookup (tab[key]) to be unsafe bool relaxed_pointer_const = false; // allow const correctness to be relaxed on pointers bool version_2_syntax = false; // use syntax version 2 bool gen2_make_syntax = false; // only new make syntax is allowed (no [[...]] or [{...}]) diff --git a/include/daScript/simulate/runtime_table_nodes.h b/include/daScript/simulate/runtime_table_nodes.h index 7c06dc759..a57ce44b1 100644 --- a/include/daScript/simulate/runtime_table_nodes.h +++ b/include/daScript/simulate/runtime_table_nodes.h @@ -63,6 +63,7 @@ namespace das __forceinline char * compute ( Context & context ) { DAS_PROFILE_NODE Table * tab = (Table *) tabExpr->evalPtr(context); + if ( tab->lock ) context.throw_error_at(debugInfo, "can't insert to a locked table"); auto key = EvalTT::eval(context,keyExpr); TableHash thh(&context,valueTypeSize); auto hfn = hash_function(context, key); diff --git a/src/ast/ast_infer_type.cpp b/src/ast/ast_infer_type.cpp index dca83aeb1..8cad1794b 100644 --- a/src/ast/ast_infer_type.cpp +++ b/src/ast/ast_infer_type.cpp @@ -59,6 +59,7 @@ namespace das { alwaysExportInitializer = prog->options.getBoolOption("always_export_initializer", false); relaxedAssign = prog->options.getBoolOption("relaxed_assign", prog->policies.relaxed_assign); relaxedPointerConst = prog->options.getBoolOption("relaxed_pointer_const", prog->policies.relaxed_pointer_const); + unsafeTableLookup = prog->options.getBoolOption("unsafe_table_lookup", prog->policies.unsafe_table_lookup); } bool finished() const { return !needRestart; } bool verbose = true; @@ -100,6 +101,7 @@ namespace das { bool alwaysExportInitializer = false; bool relaxedAssign = false; bool relaxedPointerConst = false; + bool unsafeTableLookup = false; public: vector extraFunctions; protected: @@ -4678,6 +4680,10 @@ namespace das { return pCall; } } + if ( unsafeTableLookup && !safeExpression(expr) ) { + error("table index requires unsafe", "use 'get_value', 'insert', 'insert_clone' or 'emplace' instead. consider 'get'", "", + expr->at, CompilationError::unsafe); + } expr->type = make_smart(*seT->secondType); expr->type->ref = true; expr->type->constant |= seT->constant; @@ -7271,6 +7277,21 @@ namespace das { } } } + if ( unsafeTableLookup && var->init && var->type && !var->type->ref ) { // we are looking for tab[at] to make it safe + auto pInit = var->init.get(); + if ( pInit->rtti_isR2V() ) { + pInit = static_cast(pInit)->subexpr.get(); + } + if ( pInit->rtti_isAt() ) { + auto pAt = static_cast(pInit); + if ( pAt->subexpr->type && pAt->subexpr->type->isGoodTableType() ) { + if ( !pAt->alwaysSafe ) { + pAt->alwaysSafe = true; + reportAstChanged(); + } + } + } + } verifyType(var->type); return Visitor::visitLet(expr,var,last); } diff --git a/src/ast/ast_lint.cpp b/src/ast/ast_lint.cpp index 21d30639f..dad4ad7b7 100644 --- a/src/ast/ast_lint.cpp +++ b/src/ast/ast_lint.cpp @@ -832,6 +832,7 @@ namespace das { "indenting", Type::tInt, "no_unsafe_uninitialized_structures", Type::tBool, "relaxed_pointer_const", Type::tBool, + "unsafe_table_lookup", Type::tBool, // debugger "debugger", Type::tBool, // profiler diff --git a/src/builtin/builtin.das b/src/builtin/builtin.das index 52c679785..85185aeea 100644 --- a/src/builtin/builtin.das +++ b/src/builtin/builtin.das @@ -414,6 +414,24 @@ def get(Tab:table;at:keyT|#;blk:block<(var p:void?):void>) concept_assert(false,"get(table, ...) is not supported; use 'key_exists' instead") return false +def get_value(Tab:table ==const;at:keyT|#):valT + concept_assert(false,"can't get value from const table, use Tab?[key] or 'get' instead") + return type + +def get_value(var Tab:table>;at:keyT|#):smart_ptr + concept_assert(false,"can't get smart_ptr value from table") + return <- [[smart_ptr]] + +def get_value(var Tab:table;at:keyT|#):valT + static_if typeinfo(is_void type) + concept_assert(false,"can't get value, which is void") + return type + static_elif typeinfo(can_copy type) + return unsafe(Tab[at]) + else + concept_assert(false,"can't get value, which can't be copied") + return type + // find if exists [deprecated(message="use tab?[key] or 'get' instead")] @@ -516,6 +534,49 @@ def erase(var Tab:table;at:keyT|#):bool def insert(var Tab:table;at:keyT|#) __builtin_table_set_insert(Tab,at) +def insert_clone(var Tab:table;at:keyT|#;var val:valT ==const|#) + static_if typeinfo(can_clone val) + unsafe(Tab[at]) := val + else + concept_assert(false,"can't insert value, which can't be cloned") + +def insert_clone(var Tab:table;at:keyT|#;val:valT ==const|#) + static_if typeinfo(can_clone val) + if typeinfo(can_clone_from_const val) + unsafe(Tab[at]) := val + else + concept_assert(false,"can't insert value, which can't be cloned from const") + else + concept_assert(false,"can't insert value, which can't be cloned") + +def insert(var Tab:table;at:keyT|#;var val:valT ==const|#) + static_if typeinfo(can_copy type) + unsafe(Tab[at]) = val + else + concept_assert(false,"can't insert value, which can't be copied") + +def insert(var Tab:table;at:keyT|#;val:valT ==const|#) + static_if typeinfo(can_copy type) + static_if typeinfo(can_clone_from_const val) + unsafe(Tab[at]) = val + else + concept_assert(false,"can't insert value, which can't be cloned from const") + else + concept_assert(false,"can't insert value, which can't be copied") + +def emplace(var Tab:table;at:keyT|#;var val:valT-#&) + static_if typeinfo(can_move val) + unsafe(Tab[at]) <- val + else + concept_assert(false,"can't emplace value, which can't be moved") + +def emplace(var Tab:table>;at:keyT|#;var val:smart_ptr&) + static_if typeinfo(can_move val) + unsafe + Tab[at] <- val + else + concept_assert(false,"can't emplace value, which can't be moved") + def key_exists(Tab:table|#;at:string#):bool let at_nt := at return __builtin_table_key_exists(Tab,at_nt) @@ -596,13 +657,13 @@ def clone(var a:table;b:table|#) def clone(var a:table;b:table|#) clear(a) for k,v in keys(b),values(b) - a[k] := v + unsafe(a[k]) := v def clone(var a:table;b:table|#) clear(a) for k,v in keys(b),values(b) let kk := k - a[kk] := v + unsafe(a[kk]) := v [unsafe_outside_of_for,nodiscard] def keys(a:table|#) : iterator @@ -807,7 +868,7 @@ def to_array_move(var a:auto(TT) ==const) : array def to_table(a:tuple[]) : table var tab : table for x in a - tab[x._0] := x._1 + unsafe(tab[x._0]) := x._1 return <- tab [skip_lock_check] @@ -841,9 +902,9 @@ def to_table_move(a:auto(keyT)) : table def to_table_move(var a:tuple) : table var tab : table static_if typeinfo(can_copy type) - tab[a._0] = a._1 + unsafe(tab[a._0]) = a._1 static_elif typeinfo(can_move type) - tab[a._0] <- a._1 + unsafe(tab[a._0]) <- a._1 else concept_assert(false,"this array can't be copied or moved") return <- tab @@ -853,10 +914,10 @@ def to_table_move(var a:tuple[]) : table static_if typeinfo(can_copy type) for x in a - tab[x._0] = x._1 + unsafe(tab[x._0]) = x._1 static_elif typeinfo(can_move type) for x in a - tab[x._0] <- x._1 + unsafe(tab[x._0]) <- x._1 else concept_assert(false,"this array can't be copied or moved") return <- tab @@ -866,10 +927,10 @@ def to_table_move(var a:array>) : table static_if typeinfo(can_copy type) for x in a - tab[x._0] = x._1 + unsafe(tab[x._0]) = x._1 static_elif typeinfo(can_move type) for x in a - tab[x._0] <- x._1 + unsafe(tab[x._0]) <- x._1 else concept_assert(false,"this array can't be copied or moved") return <- tab diff --git a/src/builtin/builtin.das.inc b/src/builtin/builtin.das.inc index 2de36c39a..257afe07d 100644 --- a/src/builtin/builtin.das.inc +++ b/src/builtin/builtin.das.inc @@ -2106,6 +2106,111 @@ static unsigned char builtin_das[] = { 0x72,0x6e,0x20,0x66,0x61,0x6c,0x73,0x65, 0x0a, 0x0a, +0x64,0x65,0x66,0x20,0x67,0x65,0x74,0x5f, +0x76,0x61,0x6c,0x75,0x65,0x28,0x54,0x61, +0x62,0x3a,0x74,0x61,0x62,0x6c,0x65,0x3c, +0x61,0x75,0x74,0x6f,0x28,0x6b,0x65,0x79, +0x54,0x29,0x3b,0x61,0x75,0x74,0x6f,0x28, +0x76,0x61,0x6c,0x54,0x29,0x3e,0x20,0x3d, +0x3d,0x63,0x6f,0x6e,0x73,0x74,0x3b,0x61, +0x74,0x3a,0x6b,0x65,0x79,0x54,0x7c,0x23, +0x29,0x3a,0x76,0x61,0x6c,0x54,0x0a, +0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x63, +0x65,0x70,0x74,0x5f,0x61,0x73,0x73,0x65, +0x72,0x74,0x28,0x66,0x61,0x6c,0x73,0x65, +0x2c,0x22,0x63,0x61,0x6e,0x27,0x74,0x20, +0x67,0x65,0x74,0x20,0x76,0x61,0x6c,0x75, +0x65,0x20,0x66,0x72,0x6f,0x6d,0x20,0x63, +0x6f,0x6e,0x73,0x74,0x20,0x74,0x61,0x62, +0x6c,0x65,0x2c,0x20,0x75,0x73,0x65,0x20, +0x54,0x61,0x62,0x3f,0x5b,0x6b,0x65,0x79, +0x5d,0x20,0x6f,0x72,0x20,0x27,0x67,0x65, +0x74,0x27,0x20,0x69,0x6e,0x73,0x74,0x65, +0x61,0x64,0x22,0x29,0x0a, +0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x74,0x79,0x70,0x65,0x3c, +0x76,0x61,0x6c,0x54,0x3e,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x67,0x65,0x74,0x5f, +0x76,0x61,0x6c,0x75,0x65,0x28,0x76,0x61, +0x72,0x20,0x54,0x61,0x62,0x3a,0x74,0x61, +0x62,0x6c,0x65,0x3c,0x61,0x75,0x74,0x6f, +0x28,0x6b,0x65,0x79,0x54,0x29,0x3b,0x73, +0x6d,0x61,0x72,0x74,0x5f,0x70,0x74,0x72, +0x3c,0x61,0x75,0x74,0x6f,0x28,0x76,0x61, +0x6c,0x54,0x29,0x3e,0x3e,0x3b,0x61,0x74, +0x3a,0x6b,0x65,0x79,0x54,0x7c,0x23,0x29, +0x3a,0x73,0x6d,0x61,0x72,0x74,0x5f,0x70, +0x74,0x72,0x3c,0x76,0x61,0x6c,0x54,0x3e, +0x0a, +0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x63, +0x65,0x70,0x74,0x5f,0x61,0x73,0x73,0x65, +0x72,0x74,0x28,0x66,0x61,0x6c,0x73,0x65, +0x2c,0x22,0x63,0x61,0x6e,0x27,0x74,0x20, +0x67,0x65,0x74,0x20,0x73,0x6d,0x61,0x72, +0x74,0x5f,0x70,0x74,0x72,0x20,0x76,0x61, +0x6c,0x75,0x65,0x20,0x66,0x72,0x6f,0x6d, +0x20,0x74,0x61,0x62,0x6c,0x65,0x22,0x29, +0x0a, +0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x3c,0x2d,0x20,0x5b,0x5b, +0x73,0x6d,0x61,0x72,0x74,0x5f,0x70,0x74, +0x72,0x3c,0x76,0x61,0x6c,0x54,0x3e,0x5d, +0x5d,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x67,0x65,0x74,0x5f, +0x76,0x61,0x6c,0x75,0x65,0x28,0x76,0x61, +0x72,0x20,0x54,0x61,0x62,0x3a,0x74,0x61, +0x62,0x6c,0x65,0x3c,0x61,0x75,0x74,0x6f, +0x28,0x6b,0x65,0x79,0x54,0x29,0x3b,0x61, +0x75,0x74,0x6f,0x28,0x76,0x61,0x6c,0x54, +0x29,0x3e,0x3b,0x61,0x74,0x3a,0x6b,0x65, +0x79,0x54,0x7c,0x23,0x29,0x3a,0x76,0x61, +0x6c,0x54,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x69, +0x73,0x5f,0x76,0x6f,0x69,0x64,0x20,0x74, +0x79,0x70,0x65,0x3c,0x76,0x61,0x6c,0x54, +0x3e,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x67,0x65,0x74,0x20, +0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x77, +0x68,0x69,0x63,0x68,0x20,0x69,0x73,0x20, +0x76,0x6f,0x69,0x64,0x22,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x79,0x70,0x65,0x3c,0x76,0x61,0x6c,0x54, +0x3e,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x65,0x6c,0x69,0x66,0x20, +0x74,0x79,0x70,0x65,0x69,0x6e,0x66,0x6f, +0x28,0x63,0x61,0x6e,0x5f,0x63,0x6f,0x70, +0x79,0x20,0x74,0x79,0x70,0x65,0x3c,0x76, +0x61,0x6c,0x54,0x3e,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x75, +0x6e,0x73,0x61,0x66,0x65,0x28,0x54,0x61, +0x62,0x5b,0x61,0x74,0x5d,0x29,0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x67,0x65,0x74,0x20, +0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x77, +0x68,0x69,0x63,0x68,0x20,0x63,0x61,0x6e, +0x27,0x74,0x20,0x62,0x65,0x20,0x63,0x6f, +0x70,0x69,0x65,0x64,0x22,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x79,0x70,0x65,0x3c,0x76,0x61,0x6c,0x54, +0x3e,0x0a, +0x0a, 0x2f,0x2f,0x20,0x66,0x69,0x6e,0x64,0x20, 0x69,0x66,0x20,0x65,0x78,0x69,0x73,0x74, 0x73,0x0a, @@ -2627,6 +2732,250 @@ static unsigned char builtin_das[] = { 0x69,0x6e,0x73,0x65,0x72,0x74,0x28,0x54, 0x61,0x62,0x2c,0x61,0x74,0x29,0x0a, 0x0a, +0x64,0x65,0x66,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x5f,0x63,0x6c,0x6f,0x6e,0x65, +0x28,0x76,0x61,0x72,0x20,0x54,0x61,0x62, +0x3a,0x74,0x61,0x62,0x6c,0x65,0x3c,0x61, +0x75,0x74,0x6f,0x28,0x6b,0x65,0x79,0x54, +0x29,0x3b,0x61,0x75,0x74,0x6f,0x28,0x76, +0x61,0x6c,0x54,0x29,0x3e,0x3b,0x61,0x74, +0x3a,0x6b,0x65,0x79,0x54,0x7c,0x23,0x3b, +0x76,0x61,0x72,0x20,0x76,0x61,0x6c,0x3a, +0x76,0x61,0x6c,0x54,0x20,0x3d,0x3d,0x63, +0x6f,0x6e,0x73,0x74,0x7c,0x23,0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x63,0x6c,0x6f,0x6e,0x65, +0x20,0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x54, +0x61,0x62,0x5b,0x61,0x74,0x5d,0x29,0x20, +0x3a,0x3d,0x20,0x76,0x61,0x6c,0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x20,0x76,0x61,0x6c,0x75,0x65, +0x2c,0x20,0x77,0x68,0x69,0x63,0x68,0x20, +0x63,0x61,0x6e,0x27,0x74,0x20,0x62,0x65, +0x20,0x63,0x6c,0x6f,0x6e,0x65,0x64,0x22, +0x29,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x5f,0x63,0x6c,0x6f,0x6e,0x65, +0x28,0x76,0x61,0x72,0x20,0x54,0x61,0x62, +0x3a,0x74,0x61,0x62,0x6c,0x65,0x3c,0x61, +0x75,0x74,0x6f,0x28,0x6b,0x65,0x79,0x54, +0x29,0x3b,0x61,0x75,0x74,0x6f,0x28,0x76, +0x61,0x6c,0x54,0x29,0x3e,0x3b,0x61,0x74, +0x3a,0x6b,0x65,0x79,0x54,0x7c,0x23,0x3b, +0x76,0x61,0x6c,0x3a,0x76,0x61,0x6c,0x54, +0x20,0x3d,0x3d,0x63,0x6f,0x6e,0x73,0x74, +0x7c,0x23,0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x63,0x6c,0x6f,0x6e,0x65, +0x20,0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x66,0x20,0x74,0x79,0x70,0x65,0x69, +0x6e,0x66,0x6f,0x28,0x63,0x61,0x6e,0x5f, +0x63,0x6c,0x6f,0x6e,0x65,0x5f,0x66,0x72, +0x6f,0x6d,0x5f,0x63,0x6f,0x6e,0x73,0x74, +0x20,0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x54,0x61,0x62,0x5b,0x61, +0x74,0x5d,0x29,0x20,0x3a,0x3d,0x20,0x76, +0x61,0x6c,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x65,0x6c,0x73,0x65,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x63, +0x65,0x70,0x74,0x5f,0x61,0x73,0x73,0x65, +0x72,0x74,0x28,0x66,0x61,0x6c,0x73,0x65, +0x2c,0x22,0x63,0x61,0x6e,0x27,0x74,0x20, +0x69,0x6e,0x73,0x65,0x72,0x74,0x20,0x76, +0x61,0x6c,0x75,0x65,0x2c,0x20,0x77,0x68, +0x69,0x63,0x68,0x20,0x63,0x61,0x6e,0x27, +0x74,0x20,0x62,0x65,0x20,0x63,0x6c,0x6f, +0x6e,0x65,0x64,0x20,0x66,0x72,0x6f,0x6d, +0x20,0x63,0x6f,0x6e,0x73,0x74,0x22,0x29, +0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x20,0x76,0x61,0x6c,0x75,0x65, +0x2c,0x20,0x77,0x68,0x69,0x63,0x68,0x20, +0x63,0x61,0x6e,0x27,0x74,0x20,0x62,0x65, +0x20,0x63,0x6c,0x6f,0x6e,0x65,0x64,0x22, +0x29,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x28,0x76,0x61,0x72,0x20,0x54, +0x61,0x62,0x3a,0x74,0x61,0x62,0x6c,0x65, +0x3c,0x61,0x75,0x74,0x6f,0x28,0x6b,0x65, +0x79,0x54,0x29,0x3b,0x61,0x75,0x74,0x6f, +0x28,0x76,0x61,0x6c,0x54,0x29,0x3e,0x3b, +0x61,0x74,0x3a,0x6b,0x65,0x79,0x54,0x7c, +0x23,0x3b,0x76,0x61,0x72,0x20,0x76,0x61, +0x6c,0x3a,0x76,0x61,0x6c,0x54,0x20,0x3d, +0x3d,0x63,0x6f,0x6e,0x73,0x74,0x7c,0x23, +0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x63,0x6f,0x70,0x79,0x20, +0x74,0x79,0x70,0x65,0x3c,0x76,0x61,0x6c, +0x54,0x3e,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x54, +0x61,0x62,0x5b,0x61,0x74,0x5d,0x29,0x20, +0x3d,0x20,0x76,0x61,0x6c,0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x20,0x76,0x61,0x6c,0x75,0x65, +0x2c,0x20,0x77,0x68,0x69,0x63,0x68,0x20, +0x63,0x61,0x6e,0x27,0x74,0x20,0x62,0x65, +0x20,0x63,0x6f,0x70,0x69,0x65,0x64,0x22, +0x29,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x28,0x76,0x61,0x72,0x20,0x54, +0x61,0x62,0x3a,0x74,0x61,0x62,0x6c,0x65, +0x3c,0x61,0x75,0x74,0x6f,0x28,0x6b,0x65, +0x79,0x54,0x29,0x3b,0x61,0x75,0x74,0x6f, +0x28,0x76,0x61,0x6c,0x54,0x29,0x3e,0x3b, +0x61,0x74,0x3a,0x6b,0x65,0x79,0x54,0x7c, +0x23,0x3b,0x76,0x61,0x6c,0x3a,0x76,0x61, +0x6c,0x54,0x20,0x3d,0x3d,0x63,0x6f,0x6e, +0x73,0x74,0x7c,0x23,0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x63,0x6f,0x70,0x79,0x20, +0x74,0x79,0x70,0x65,0x3c,0x76,0x61,0x6c, +0x54,0x3e,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x69, +0x66,0x20,0x74,0x79,0x70,0x65,0x69,0x6e, +0x66,0x6f,0x28,0x63,0x61,0x6e,0x5f,0x63, +0x6c,0x6f,0x6e,0x65,0x5f,0x66,0x72,0x6f, +0x6d,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x20, +0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x54,0x61,0x62,0x5b,0x61, +0x74,0x5d,0x29,0x20,0x3d,0x20,0x76,0x61, +0x6c,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x65,0x6c,0x73,0x65,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x63, +0x65,0x70,0x74,0x5f,0x61,0x73,0x73,0x65, +0x72,0x74,0x28,0x66,0x61,0x6c,0x73,0x65, +0x2c,0x22,0x63,0x61,0x6e,0x27,0x74,0x20, +0x69,0x6e,0x73,0x65,0x72,0x74,0x20,0x76, +0x61,0x6c,0x75,0x65,0x2c,0x20,0x77,0x68, +0x69,0x63,0x68,0x20,0x63,0x61,0x6e,0x27, +0x74,0x20,0x62,0x65,0x20,0x63,0x6c,0x6f, +0x6e,0x65,0x64,0x20,0x66,0x72,0x6f,0x6d, +0x20,0x63,0x6f,0x6e,0x73,0x74,0x22,0x29, +0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x69,0x6e,0x73,0x65, +0x72,0x74,0x20,0x76,0x61,0x6c,0x75,0x65, +0x2c,0x20,0x77,0x68,0x69,0x63,0x68,0x20, +0x63,0x61,0x6e,0x27,0x74,0x20,0x62,0x65, +0x20,0x63,0x6f,0x70,0x69,0x65,0x64,0x22, +0x29,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x65,0x6d,0x70,0x6c, +0x61,0x63,0x65,0x28,0x76,0x61,0x72,0x20, +0x54,0x61,0x62,0x3a,0x74,0x61,0x62,0x6c, +0x65,0x3c,0x61,0x75,0x74,0x6f,0x28,0x6b, +0x65,0x79,0x54,0x29,0x3b,0x61,0x75,0x74, +0x6f,0x28,0x76,0x61,0x6c,0x54,0x29,0x3e, +0x3b,0x61,0x74,0x3a,0x6b,0x65,0x79,0x54, +0x7c,0x23,0x3b,0x76,0x61,0x72,0x20,0x76, +0x61,0x6c,0x3a,0x76,0x61,0x6c,0x54,0x2d, +0x23,0x26,0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x6d,0x6f,0x76,0x65,0x20, +0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x54, +0x61,0x62,0x5b,0x61,0x74,0x5d,0x29,0x20, +0x3c,0x2d,0x20,0x76,0x61,0x6c,0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x65,0x6d,0x70,0x6c, +0x61,0x63,0x65,0x20,0x76,0x61,0x6c,0x75, +0x65,0x2c,0x20,0x77,0x68,0x69,0x63,0x68, +0x20,0x63,0x61,0x6e,0x27,0x74,0x20,0x62, +0x65,0x20,0x6d,0x6f,0x76,0x65,0x64,0x22, +0x29,0x0a, +0x0a, +0x64,0x65,0x66,0x20,0x65,0x6d,0x70,0x6c, +0x61,0x63,0x65,0x28,0x76,0x61,0x72,0x20, +0x54,0x61,0x62,0x3a,0x74,0x61,0x62,0x6c, +0x65,0x3c,0x61,0x75,0x74,0x6f,0x28,0x6b, +0x65,0x79,0x54,0x29,0x3b,0x73,0x6d,0x61, +0x72,0x74,0x5f,0x70,0x74,0x72,0x3c,0x61, +0x75,0x74,0x6f,0x28,0x76,0x61,0x6c,0x54, +0x29,0x3e,0x3e,0x3b,0x61,0x74,0x3a,0x6b, +0x65,0x79,0x54,0x7c,0x23,0x3b,0x76,0x61, +0x72,0x20,0x76,0x61,0x6c,0x3a,0x73,0x6d, +0x61,0x72,0x74,0x5f,0x70,0x74,0x72,0x3c, +0x76,0x61,0x6c,0x54,0x3e,0x26,0x29,0x0a, +0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, +0x69,0x63,0x5f,0x69,0x66,0x20,0x74,0x79, +0x70,0x65,0x69,0x6e,0x66,0x6f,0x28,0x63, +0x61,0x6e,0x5f,0x6d,0x6f,0x76,0x65,0x20, +0x76,0x61,0x6c,0x29,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x75,0x6e,0x73,0x61,0x66,0x65,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x54,0x61,0x62,0x5b, +0x61,0x74,0x5d,0x20,0x3c,0x2d,0x20,0x76, +0x61,0x6c,0x0a, +0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, +0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x63,0x6f,0x6e,0x63,0x65,0x70,0x74,0x5f, +0x61,0x73,0x73,0x65,0x72,0x74,0x28,0x66, +0x61,0x6c,0x73,0x65,0x2c,0x22,0x63,0x61, +0x6e,0x27,0x74,0x20,0x65,0x6d,0x70,0x6c, +0x61,0x63,0x65,0x20,0x76,0x61,0x6c,0x75, +0x65,0x2c,0x20,0x77,0x68,0x69,0x63,0x68, +0x20,0x63,0x61,0x6e,0x27,0x74,0x20,0x62, +0x65,0x20,0x6d,0x6f,0x76,0x65,0x64,0x22, +0x29,0x0a, +0x0a, 0x64,0x65,0x66,0x20,0x6b,0x65,0x79,0x5f, 0x65,0x78,0x69,0x73,0x74,0x73,0x28,0x54, 0x61,0x62,0x3a,0x74,0x61,0x62,0x6c,0x65, @@ -2974,7 +3323,8 @@ static unsigned char builtin_das[] = { 0x61,0x6c,0x75,0x65,0x73,0x28,0x62,0x29, 0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x61,0x5b,0x6b,0x5d,0x20,0x3a,0x3d,0x20, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x61, +0x5b,0x6b,0x5d,0x29,0x20,0x3a,0x3d,0x20, 0x76,0x0a, 0x0a, 0x64,0x65,0x66,0x20,0x63,0x6c,0x6f,0x6e, @@ -2996,7 +3346,8 @@ static unsigned char builtin_das[] = { 0x6c,0x65,0x74,0x20,0x6b,0x6b,0x20,0x3a, 0x3d,0x20,0x6b,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x61,0x5b,0x6b,0x6b,0x5d,0x20,0x3a,0x3d, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x61, +0x5b,0x6b,0x6b,0x5d,0x29,0x20,0x3a,0x3d, 0x20,0x76,0x0a, 0x0a, 0x5b,0x75,0x6e,0x73,0x61,0x66,0x65,0x5f, @@ -4003,8 +4354,9 @@ static unsigned char builtin_das[] = { 0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20, 0x78,0x20,0x69,0x6e,0x20,0x61,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x74,0x61,0x62,0x5b,0x78,0x2e,0x5f,0x30, -0x5d,0x20,0x3a,0x3d,0x20,0x78,0x2e,0x5f, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x74, +0x61,0x62,0x5b,0x78,0x2e,0x5f,0x30,0x5d, +0x29,0x20,0x3a,0x3d,0x20,0x78,0x2e,0x5f, 0x31,0x0a, 0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, 0x72,0x6e,0x20,0x3c,0x2d,0x20,0x74,0x61, @@ -4141,8 +4493,9 @@ static unsigned char builtin_das[] = { 0x74,0x79,0x70,0x65,0x3c,0x76,0x61,0x6c, 0x54,0x3e,0x29,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x74,0x61,0x62,0x5b,0x61,0x2e,0x5f,0x30, -0x5d,0x20,0x3d,0x20,0x61,0x2e,0x5f,0x31, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x74, +0x61,0x62,0x5b,0x61,0x2e,0x5f,0x30,0x5d, +0x29,0x20,0x3d,0x20,0x61,0x2e,0x5f,0x31, 0x0a, 0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, 0x69,0x63,0x5f,0x65,0x6c,0x69,0x66,0x20, @@ -4151,8 +4504,9 @@ static unsigned char builtin_das[] = { 0x65,0x20,0x74,0x79,0x70,0x65,0x3c,0x76, 0x61,0x6c,0x54,0x3e,0x29,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x74,0x61,0x62,0x5b,0x61,0x2e,0x5f,0x30, -0x5d,0x20,0x3c,0x2d,0x20,0x61,0x2e,0x5f, +0x75,0x6e,0x73,0x61,0x66,0x65,0x28,0x74, +0x61,0x62,0x5b,0x61,0x2e,0x5f,0x30,0x5d, +0x29,0x20,0x3c,0x2d,0x20,0x61,0x2e,0x5f, 0x31,0x0a, 0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, 0x0a, @@ -4198,8 +4552,9 @@ static unsigned char builtin_das[] = { 0x66,0x6f,0x72,0x20,0x78,0x20,0x69,0x6e, 0x20,0x61,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x74,0x61,0x62,0x5b, -0x78,0x2e,0x5f,0x30,0x5d,0x20,0x3d,0x20, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x74,0x61,0x62,0x5b,0x78, +0x2e,0x5f,0x30,0x5d,0x29,0x20,0x3d,0x20, 0x78,0x2e,0x5f,0x31,0x0a, 0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, 0x69,0x63,0x5f,0x65,0x6c,0x69,0x66,0x20, @@ -4211,8 +4566,9 @@ static unsigned char builtin_das[] = { 0x66,0x6f,0x72,0x20,0x78,0x20,0x69,0x6e, 0x20,0x61,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x74,0x61,0x62,0x5b, -0x78,0x2e,0x5f,0x30,0x5d,0x20,0x3c,0x2d, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x74,0x61,0x62,0x5b,0x78, +0x2e,0x5f,0x30,0x5d,0x29,0x20,0x3c,0x2d, 0x20,0x78,0x2e,0x5f,0x31,0x0a, 0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, 0x0a, @@ -4258,8 +4614,9 @@ static unsigned char builtin_das[] = { 0x66,0x6f,0x72,0x20,0x78,0x20,0x69,0x6e, 0x20,0x61,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x74,0x61,0x62,0x5b, -0x78,0x2e,0x5f,0x30,0x5d,0x20,0x3d,0x20, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x74,0x61,0x62,0x5b,0x78, +0x2e,0x5f,0x30,0x5d,0x29,0x20,0x3d,0x20, 0x78,0x2e,0x5f,0x31,0x0a, 0x20,0x20,0x20,0x20,0x73,0x74,0x61,0x74, 0x69,0x63,0x5f,0x65,0x6c,0x69,0x66,0x20, @@ -4271,8 +4628,9 @@ static unsigned char builtin_das[] = { 0x66,0x6f,0x72,0x20,0x78,0x20,0x69,0x6e, 0x20,0x61,0x0a, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x74,0x61,0x62,0x5b, -0x78,0x2e,0x5f,0x30,0x5d,0x20,0x3c,0x2d, +0x20,0x20,0x20,0x20,0x75,0x6e,0x73,0x61, +0x66,0x65,0x28,0x74,0x61,0x62,0x5b,0x78, +0x2e,0x5f,0x30,0x5d,0x29,0x20,0x3c,0x2d, 0x20,0x78,0x2e,0x5f,0x31,0x0a, 0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, 0x0a, diff --git a/src/builtin/module_builtin_rtti.cpp b/src/builtin/module_builtin_rtti.cpp index b0af2854b..86137b702 100644 --- a/src/builtin/module_builtin_rtti.cpp +++ b/src/builtin/module_builtin_rtti.cpp @@ -717,6 +717,7 @@ namespace das { // rtti addField("rtti"); // language + addField("unsafe_table_lookup"); addField("relaxed_pointer_const"); addField("version_2_syntax"); addField("gen2_make_syntax"); From 2e9aee8c811d6d4c8392123193fda8b110e075a4 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Mon, 9 Dec 2024 21:09:57 -0800 Subject: [PATCH 2/3] fusion also passes tests --- src/simulate/simulate_fusion_tableindex.cpp | 2 ++ tests/archive/test_archive.das | 2 +- tests/language/containers.inc | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/simulate/simulate_fusion_tableindex.cpp b/src/simulate/simulate_fusion_tableindex.cpp index ae26eb86a..9f8de2e6b 100644 --- a/src/simulate/simulate_fusion_tableindex.cpp +++ b/src/simulate/simulate_fusion_tableindex.cpp @@ -41,6 +41,7 @@ namespace das { INLINE auto compute ( Context & context ) { \ DAS_PROFILE_NODE \ auto tab = (Table *) l.compute##COMPUTEL(context); \ + if ( tab->lock ) context.throw_error_at(debugInfo, "can't insert to a locked table"); \ auto key = EvalTT::eval(context,r.subexpr); \ TableHash thh(&context,valueTypeSize); \ auto hfn = hash_function(context, key); \ @@ -55,6 +56,7 @@ namespace das { INLINE auto compute ( Context & context ) { \ DAS_PROFILE_NODE \ auto tab = (Table *) l.compute##COMPUTEL(context); \ + if ( tab->lock ) context.throw_error_at(debugInfo, "can't insert to a locked table"); \ auto key = *((CTYPE *)r.compute##COMPUTER(context)); \ TableHash thh(&context,valueTypeSize); \ auto hfn = hash_function(context, key); \ diff --git a/tests/archive/test_archive.das b/tests/archive/test_archive.das index 8c207ef9b..2087e0db5 100644 --- a/tests/archive/test_archive.das +++ b/tests/archive/test_archive.das @@ -34,7 +34,7 @@ def test_save_and_load_mem_table ( t:T? ) delete data t |> equal( length(test), length(reference)) for k in keys(reference) - t |> equal( reference[k], test?[k] ?? -100500) + t |> equal( reference?[k] ?? -1, test?[k] ?? -100500) [test] def test_save_and_load_mem_array ( t:T? ) diff --git a/tests/language/containers.inc b/tests/language/containers.inc index dfa5d0f2b..ddaed0dd0 100644 --- a/tests/language/containers.inc +++ b/tests/language/containers.inc @@ -86,7 +86,7 @@ def table_ops ( t : T?; var a:table; var e:Foo; var et:Foo implicit ) t |> equal(1, a[1].a) t |> equal(2, length(a) ) for k in keys(a) - t |> equal(1, a[k].a) + t |> equal(1, a?[k]?.a ?? -1) for k in keys(a) t |> success ( k==0 || k==1 ) for v in values(a) From 6fa7d07c2cfad4b6e9e5f38b3b328dea3b774957 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Mon, 9 Dec 2024 21:14:49 -0800 Subject: [PATCH 3/3] also with JIT --- src/builtin/module_jit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/builtin/module_jit.cpp b/src/builtin/module_jit.cpp index 1cfa5ac05..101c3fae6 100644 --- a/src/builtin/module_jit.cpp +++ b/src/builtin/module_jit.cpp @@ -326,6 +326,7 @@ extern "C" { template int32_t jit_table_at ( Table * tab, KeyType key, int32_t valueTypeSize, Context * context, LineInfoArg * at ) { + if ( tab->lock ) context->throw_error_at(at, "can't insert to a locked table"); TableHash thh(context,valueTypeSize); auto hfn = hash_function(*context, key); return thh.reserve(*tab, key, hfn, at);