From 3eb70efeea83db01550cc8df12beaa90d4766b98 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Fri, 21 Jun 2024 12:45:31 +0300 Subject: [PATCH] Migrating to new BHL efficient native array wrappers --- src/bind.inc.php | 83 +++++++++++++------------ tpl/bhl_bind_macro.twig | 127 ++++++++++---------------------------- tpl/codegen_autobind.twig | 4 +- 3 files changed, 78 insertions(+), 136 deletions(-) diff --git a/src/bind.inc.php b/src/bind.inc.php index c5266a8..56345f8 100644 --- a/src/bind.inc.php +++ b/src/bind.inc.php @@ -17,7 +17,6 @@ function supported_tokens() 'bhl_native_class_params', 'bhl_native_prefix', 'bhl_custom_rw', - 'bhl_no_array_proxy', 'bhl_get', 'bhl_set', 'bhl_ref_arg', @@ -40,6 +39,8 @@ function codegen( $options['imports'] = array(); if(!isset($options['register_class'])) $options['register_class'] = 'BHL_AutoBindings'; + if(!isset($options['namespace'])) + $options['namespace'] = 'bhl'; if(isset($options['plugins'])) { @@ -81,49 +82,53 @@ function prepare_meta(\mtgMetaInfo $orig) $meta = unserialize(serialize($orig)); $arr_proxies = array(); + $traversed = array(); foreach($meta->getUnits() as $u) - { - if($u->object instanceof \mtgMetaStruct) - { - $need_to_replace = false; - $fields = $u->object->getFields(); - //NOTE: let's replace arrays with array proxies - foreach($fields as $name => $fld) - { - if($fld->getType() instanceof \mtgArrType && !$fld->hasToken('bhl_no_array_proxy')) - { - $proxy_name = "List_{$fld->getType()->getValue()->getName()}"; - if(!isset($arr_proxies[$proxy_name])) - { - $proxy = new \mtgMetaStruct($proxy_name); - $proxy->setToken('bhl_native_arr_proxy', $fld->getType()->getValue()); - $meta->addUnit(new \mtgMetaInfoUnit('', $proxy)); - $arr_proxies[$proxy_name] = $proxy; - } - else - $proxy = $arr_proxies[$proxy_name]; - - $new_fld = new \mtgMetaField($name, new \mtgTypeRef($proxy)); - //forcing no setter - $new_fld->setToken('bhl_set', 0); - $fields[$name] = $new_fld; - - $need_to_replace = true; - } - } - - if($need_to_replace) - { - foreach($u->object->getFields() as $fld) - $u->object->delField($fld); - $u->object->setFields($fields); - } - } - } + _make_arr_proxies($arr_proxies, $meta, $u->object, $traversed); return $meta; } +function _make_arr_proxies(array &$arr_proxies, \mtgMetaInfo $meta, ?\mtgType $type, array &$traversed) +{ + if($type == null) + return; + if(isset($traversed[spl_object_hash($type)])) + return; + $traversed[spl_object_hash($type)] = true; + + if($type instanceof \mtgMetaStruct) + { + foreach($type->getFields() as $fld) + _make_arr_proxies($arr_proxies, $meta, $fld->getType(), $traversed); + + foreach($type->getFuncs() as $func) + _make_arr_proxies($arr_proxies, $meta, $func, $traversed); + } + else if($type instanceof \mtgMetaFunc) + { + $args = $type->getArgs(); + foreach($args as $arg) + _make_arr_proxies($arr_proxies, $meta, $arg->getType(), $traversed); + + $ret_type = $type->getReturnType(); + _make_arr_proxies($arr_proxies, $meta, $ret_type, $traversed); + } + else if($type instanceof \mtgArrType) + { + $vtype = $type->getValue(); + + $proxy_name = "List_{$vtype->getName()}"; + if(isset($arr_proxies[$proxy_name])) + return; + + $proxy = new \mtgMetaStruct($proxy_name); + $proxy->setToken('bhl_native_arr_proxy', $vtype); + $meta->addUnit(new \mtgMetaInfoUnit('', $proxy)); + $arr_proxies[$proxy_name] = $proxy; + } +} + function add_twig_support(\Twig\Environment $twig) { $twig->addFunction(new \Twig\TwigFunction('plugins_codegen_decls', diff --git a/tpl/bhl_bind_macro.twig b/tpl/bhl_bind_macro.twig index 3c79e8c..5e37db7 100644 --- a/tpl/bhl_bind_macro.twig +++ b/tpl/bhl_bind_macro.twig @@ -410,13 +410,13 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- if type == 'any[]'-%} {{native}} = ValList.New(frm.vm); {%~ endif -%} - var dvl = (ValList){{value}}._obj; + var _arr_type = (ArrayTypeSymbol){{value}}.type; {{native}}.Clear(); - for(int i=0;i( + new Origin(), + "{{o.name}}", + (v) => { +#if !BHL_FRONT + {#TODO: get rid of replace hack below#} + {{('var ' ~ _self.val2native(token(o, 'bhl_native_arr_proxy'), 'v', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}}; + return tmp; +#else + return null; #endif }, - null); - cl.Define(vs); - } - { - var fn = new FuncSymbolNative(new Origin(), "At", {{token(o, 'bhl_native_arr_proxy')|bhl_type_ref}}, - delegate(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status) - { + (_vm, itype, n) => { #if !BHL_FRONT - var val_idx = stack.Pop(); - var val_lst = stack.Pop(); - - var v = ((List<{{token(o, 'bhl_native_arr_proxy')|native_type}}>)val_lst.obj)[(int)val_idx._num]; - var dv = Val.New(frm.vm); - - {{ _self.native2val(token(o, 'bhl_native_arr_proxy'), 'v', 'dv') }}; - stack.Push(dv); - - val_idx.Release(); - val_lst.Release(); + var v = Val.New(_vm); + {{ _self.native2val(token(o, 'bhl_native_arr_proxy'), 'n', 'v')}}; + return v; +#else + return null; #endif - return null; - }, - new FuncArgSymbol("idx", Types.Int) - ); - cl.Define(fn); - } - { - var fn = new FuncSymbolNative(new Origin(), "Add", Types.Void, - delegate(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status) - { -#if !BHL_FRONT - var val = stack.Pop(); - var val_lst = stack.Pop(); - - {#TODO: get rid of replace hack below#} - {{('var ' ~ _self.val2native(token(o, 'bhl_native_arr_proxy'), 'val', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}}; - var lst = ((List<{{token(o, 'bhl_native_arr_proxy')|native_type}}>)val_lst.obj); - lst.Add(tmp); - - val.Release(); - val_lst.Release(); -#endif - return null; - }, - new FuncArgSymbol("v", {{token(o, 'bhl_native_arr_proxy')|bhl_type_ref}}) - ); - cl.Define(fn); - } - { - var fn = new FuncSymbolNative(new Origin(), "Set", Types.Void, - delegate(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status) - { -#if !BHL_FRONT - var index = stack.Pop(); - var val = stack.Pop(); - var val_lst = stack.Pop(); - - {#TODO: get rid of replace hack below#} - {{('var ' ~ _self.val2native(token(o, 'bhl_native_arr_proxy'), 'val', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}}; - var lst = ((List<{{token(o, 'bhl_native_arr_proxy')|native_type}}>)val_lst.obj); - lst[(int)index._num] = tmp; - - val.Release(); - index.Release(); - val_lst.Release(); -#endif - return null; - }, - new FuncArgSymbol("v", {{token(o, 'bhl_native_arr_proxy')|bhl_type_ref}}), - new FuncArgSymbol("idx", Types.Int) - ); - cl.Define(fn); - } + }, + {{token(o, 'bhl_native_arr_proxy')|bhl_type_ref}} + ); cl.Setup(); {{scope}}.Define(cl); } @@ -651,10 +588,10 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {% if o.parent %} types.T("{{o.parent}}"), {% else %} - new Proxy(), + new ProxyType(), {% endif %} {% if o.implements -%} - proxy_implements: new List>() { + proxy_implements: new List() { {% for imp in o.implements %} types.T("{{imp.name}}"), {% endfor %} diff --git a/tpl/codegen_autobind.twig b/tpl/codegen_autobind.twig index 8e32654..ea43fa1 100644 --- a/tpl/codegen_autobind.twig +++ b/tpl/codegen_autobind.twig @@ -11,7 +11,7 @@ using {{imp}}; {% import "bhl_bind_macro.twig" as macro %} -namespace bhl { +namespace {{namespace}} { {%- for u in meta.units ~%} {%- if u.object is instanceof('\\mtgMetaStruct') or u.object is instanceof('\\mtgMetaInterface') ~%} @@ -62,4 +62,4 @@ public static void RegisterEnd(Types types) } -} //namespace bhl +}