Migrating to new BHL efficient native array wrappers
Publish PHP Package / docker (push) Successful in 9s Details

This commit is contained in:
Pavel Shevaev 2024-06-21 12:45:31 +03:00
parent e303b703dc
commit 3eb70efeea
3 changed files with 78 additions and 136 deletions

View File

@ -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',

View File

@ -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<dvl.Count;++i)
for(int i=0;i<_arr_type.ArrCount({{value}});++i)
{
var tdv = dvl[i];
var _arr_item = _arr_type.ArrGetAt({{value}}, i);
{#TODO: get rid of replace hack below#}
{{('var ' ~ _self.val2native(type.value, 'tdv', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}};
{{('var ' ~ _self.val2native(type.value, '_arr_item', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}};
{{native}}.Add(tmp);
}
{%- endif -%}
@ -472,15 +472,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endif -%}
{%- if type is instanceof('\\mtgArrType') -%}
var dvl = ValList.New(frm.vm);
for(int i=0;i<{{native}}.Count;++i)
{
var tmp = {{native}}[i];
var tdv = bhl.Val.New(frm.vm);
{{_self.native2val(type.value, 'tmp', 'tdv')}};
dvl.lst.Add(tdv);
}
{{value}}.SetObj(dvl, Types.Array);
{{value}}.SetObj({{native}}, Types_List_{{type.value.name|norm_name}}.Value)
{%- endif -%}
{%- if type is instanceof('\\mtgBuiltinType') -%}
@ -521,92 +513,37 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endmacro -%}
{%- macro reg_native_arr_proxy(o, scope = 'types.ns') ~%}
if({{scope}}.{{o.name|ns_prefix}}Resolve("{{o.name|ns_last}}") == null)
{
var cl = new ClassSymbolNative(new Origin(), "{{o.name}}",
//constructor is not allowed
creator: null
);
{
var vs = new FieldSymbol(new Origin(), "Count", Types.Int,
delegate(VM.Frame frm, Val ctx, ref Val v, FieldSymbol fld)
{
var cl = new NativeListTypeSymbol<
#if !BHL_FRONT
v.SetNum((ctx.obj as IList).Count);
{{token(o, 'bhl_native_arr_proxy')|native_type}}
#else
object
#endif
>(
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<IType>(),
new ProxyType(),
{% endif %}
{% if o.implements -%}
proxy_implements: new List<Proxy<IType>>() {
proxy_implements: new List<ProxyType()>() {
{% for imp in o.implements %}
types.T("{{imp.name}}"),
{% endfor %}

View File

@ -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
}