<commit_before>// NativeBridge.java

package ed.js.engine;

import java.util.*;
import java.lang.reflect.*;

import ed.js.*;
import ed.js.func.*;
import ed.lang.*;

public class NativeBridge {

    private static final Object[] EMPTY_OBJET_ARRAY = new Object[0];
    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
    
    private static final Set<String> _disallowedNativeNames = new HashSet<String>();
    static {
        _disallowedNativeNames.add( "getClassLoader" );
        _disallowedNativeNames.add( "loadClass" );
    }

    public static final JSFunction getNativeFunc( final Object o , final String name ){
        if ( o == null )
            throw new IllegalArgumentException( "o can't be null" );
        
        final Class c = o.getClass();
        if ( c == JSObjectBase.class )
            return null;

        List<Method> methods = getMethods( o.getClass() , name );
        if ( methods == null || methods.size() == 0 )
            return null;
        
        return new JSFunctionCalls0(){
            public Object call( Scope s , Object params[] ){
                return callNative( s , o , name , params );
            }
        };
    }
    
    static final JSFunctionCalls0 _nativeFuncCall = new JSFunctionCalls0(){
            
            public Object call( Scope s , Object params[] ){
                
                final boolean debug = false;
                
                Scope.This temp = s._this.peek();
                if ( temp._this != null )
                    throw new RuntimeException( "why is this._this is not null : " + temp._this + " s:" + s.hashCode() );
                final Object obj = temp._nThis;
                final String name = temp._nThisFunc;
                
                if ( obj == null )
                    throw new NullPointerException( "object was null.  name was:" + name );
                
                if ( debug ) System.out.println( obj.getClass() + " : " + name );
                
                return callNative( s , obj , name , params , debug );
            }
        };
    
    private static final Map< Class , Map< String , List<Method> > > _classToMethods = new HashMap< Class , Map< String , List<Method> > >();
    
    private static List<Method> getMethods( Class c , String n ){
        Map<String,List<Method>> m = _classToMethods.get( c );
        if ( m == null ){
            m = new HashMap<String,List<Method>>();
            _classToMethods.put( c , m );
        }
        
        List<Method> l = m.get( n );
        if ( l != null )
            return l;
        
        l = new ArrayList<Method>();
        Method all[] = c.getMethods();
        Arrays.sort( all , _methodLengthComparator );
        for ( Method method : all )
            if ( method.getName().equals( n ) )
                l.add( method );
        m.put( n , l );
        return l;
    }


    public static Object callNative( Scope s , Object obj , String name , Object params[] ){
        return callNative( s , obj , name , params , false );
    }
    
    public static Object callNative( Scope s , Object obj , String name , Object params[]  , boolean debug ){
        
        if ( _disallowedNativeNames.contains( name ) )
            throw new JSException( "[" + name + "] is not allowed" );

        List<Method> methods = getMethods( obj.getClass() , name );
        if ( methods != null && methods.size() > 0 ){
            methods:
            for ( Method m : methods ){
                if ( debug ) System.out.println( "\t " + m.getName() );
                
                Object nParams[] = doParamsMatch( m.getParameterTypes() , params , debug );
                if ( nParams == null ){
                    if ( debug ) System.out.println( "\t\t boo" );
                    continue;
                }
                
                if ( debug ) System.out.println( "\t\t yay" );
                
                m.setAccessible( true );
                try {
                    Object ret = m.invoke( obj , nParams );
                    if ( ret != null ){
                        if ( ret instanceof String )
                            ret = new JSString( ret.toString() );
                        else if ( ret instanceof java.util.Date ) 
                            ret = new JSDate( (java.util.Date)ret );
                        else if ( ret instanceof java.util.Collection ){
                            if ( ! ( ret instanceof JSArray  ) ){
                                JSArray a = new JSArray();
                                for ( Object o : (Collection)ret )
                                    a.add( o );
                                ret = a;
                            }
                        }
                        else if ( ret.getClass().isArray() ){
                            if ( ret.getClass().getName().toString().length() > 3 ){ // primitive
                                JSArray a = new JSArray();
                                for ( Object o : ((Object[])ret) )
                                    a.add( o );
                                return a;<commit_msg>setThreadLocal correctly for native calls<commit_after>// NativeBridge.java

package ed.js.engine;

import java.util.*;
import java.lang.reflect.*;

import ed.js.*;
import ed.js.func.*;
import ed.lang.*;

public class NativeBridge {

    private static final Object[] EMPTY_OBJET_ARRAY = new Object[0];
    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
    
    private static final Set<String> _disallowedNativeNames = new HashSet<String>();
    static {
        _disallowedNativeNames.add( "getClassLoader" );
        _disallowedNativeNames.add( "loadClass" );
    }

    public static final JSFunction getNativeFunc( final Object o , final String name ){
        if ( o == null )
            throw new IllegalArgumentException( "o can't be null" );
        
        final Class c = o.getClass();
        if ( c == JSObjectBase.class )
            return null;

        List<Method> methods = getMethods( o.getClass() , name );
        if ( methods == null || methods.size() == 0 )
            return null;
        
        return new JSFunctionCalls0(){
            public Object call( Scope s , Object params[] ){
                return callNative( s , o , name , params );
            }
        };
    }
    
    static final JSFunctionCalls0 _nativeFuncCall = new JSFunctionCalls0(){
            
            public Object call( Scope s , Object params[] ){
                
                final boolean debug = false;
                
                Scope.This temp = s._this.peek();
                if ( temp._this != null )
                    throw new RuntimeException( "why is this._this is not null : " + temp._this + " s:" + s.hashCode() );
                final Object obj = temp._nThis;
                final String name = temp._nThisFunc;
                
                if ( obj == null )
                    throw new NullPointerException( "object was null.  name was:" + name );
                
                if ( debug ) System.out.println( obj.getClass() + " : " + name );
                
                return callNative( s , obj , name , params , debug );
            }
        };
    
    private static final Map< Class , Map< String , List<Method> > > _classToMethods = new HashMap< Class , Map< String , List<Method> > >();
    
    private static List<Method> getMethods( Class c , String n ){
        Map<String,List<Method>> m = _classToMethods.get( c );
        if ( m == null ){
            m = new HashMap<String,List<Method>>();
            _classToMethods.put( c , m );
        }
        
        List<Method> l = m.get( n );
        if ( l != null )
            return l;
        
        l = new ArrayList<Method>();
        Method all[] = c.getMethods();
        Arrays.sort( all , _methodLengthComparator );
        for ( Method method : all )
            if ( method.getName().equals( n ) )
                l.add( method );
        m.put( n , l );
        return l;
    }


    public static Object callNative( Scope s , Object obj , String name , Object params[] ){
        return callNative( s , obj , name , params , false );
    }
    
    public static Object callNative( Scope s , Object obj , String name , Object params[]  , boolean debug ){
        
        if ( _disallowedNativeNames.contains( name ) )
            throw new JSException( "[" + name + "] is not allowed" );

        List<Method> methods = getMethods( obj.getClass() , name );
        if ( methods != null && methods.size() > 0 ){
            methods:
            for ( Method m : methods ){
                if ( debug ) System.out.println( "\t " + m.getName() );
                
                Object nParams[] = doParamsMatch( m.getParameterTypes() , params , debug );
                if ( nParams == null ){
                    if ( debug ) System.out.println( "\t\t boo" );
                    continue;
                }
                
                if ( debug ) System.out.println( "\t\t yay" );
                
                m.setAccessible( true );
                try {
                    
                    Scope prev = Scope.getThreadLocal();
                    Object ret;
                    try {
                        s.makeThreadLocal();
                        ret = m.invoke( obj , nParams );
                    }
                    finally {
                        if ( prev != null )
                            prev.makeThreadLocal();
                    }
                    
                    if ( ret != null ){
                        if ( ret instanceof String )
                            ret = new JSString( ret.toString() );
                        else if ( ret instanceof java.util.Date ) 
                            ret = new JSDate( (java.util.Date)ret );
                        else if ( ret instanceof java.util.Collection ){
                            if ( ! ( ret instanceof JSArray  ) ){
                                JSArray a = new JSArray();
                                for ( Object o : (Collection)ret )
                                    a.add( o );
                                ret = a;
                            }
                        }
                        else if ( ret.getClass().isArray() ){
                            if ( ret.getClass().getName().toString().length() > 3 ){ // primitive
                                JSArray a = new JSArray();
                                for ( Object o : ((Object[])ret) )
                                    a.add( o );
                                return a;
{'fraction_non_alphanumeric': 0.10598258590019662, 'fraction_numerical': 0.0014979870798614361, 'mean_word_length': 1.2445891994116411, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '398015', 'n_tokens_mistral': 2695, 'n_tokens_neox': 2599, 'n_words': 788}