60
60
import static com .oracle .graal .python .util .PythonUtils .toTruffleStringUncached ;
61
61
import static com .oracle .graal .python .util .PythonUtils .tsLiteral ;
62
62
63
+ import java .io .File ;
63
64
import java .io .IOException ;
64
65
import java .io .InputStreamReader ;
65
66
import java .io .PrintWriter ;
66
67
import java .nio .charset .StandardCharsets ;
68
+ import java .nio .file .Files ;
69
+ import java .nio .file .Path ;
70
+ import java .nio .file .Paths ;
71
+ import java .util .Arrays ;
67
72
import java .util .List ;
68
73
import java .util .logging .Level ;
69
74
70
- import com .oracle .truffle .api .dsl .Bind ;
71
- import com .oracle .truffle .api .nodes .Node ;
72
75
import org .graalvm .nativeimage .ImageInfo ;
73
76
74
77
import com .oracle .graal .python .PythonLanguage ;
105
108
import com .oracle .graal .python .builtins .objects .type .TypeNodes .CreateTypeNode ;
106
109
import com .oracle .graal .python .lib .PyObjectCallMethodObjArgs ;
107
110
import com .oracle .graal .python .lib .PyObjectGetItem ;
108
- import com .oracle .graal .python .lib .PyObjectTypeCheck ;
109
111
import com .oracle .graal .python .nodes .ErrorMessages ;
110
112
import com .oracle .graal .python .nodes .builtins .FunctionNodes .GetCallTargetNode ;
111
113
import com .oracle .graal .python .nodes .bytecode .PBytecodeRootNode ;
131
133
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
132
134
import com .oracle .graal .python .util .PythonUtils ;
133
135
import com .oracle .truffle .api .CallTarget ;
136
+ import com .oracle .truffle .api .CompilerAsserts ;
134
137
import com .oracle .truffle .api .CompilerDirectives ;
135
138
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
136
139
import com .oracle .truffle .api .TruffleFile ;
137
140
import com .oracle .truffle .api .TruffleLanguage .Env ;
138
141
import com .oracle .truffle .api .TruffleLogger ;
142
+ import com .oracle .truffle .api .dsl .Bind ;
139
143
import com .oracle .truffle .api .dsl .Cached ;
140
144
import com .oracle .truffle .api .dsl .Cached .Shared ;
141
145
import com .oracle .truffle .api .dsl .Fallback ;
150
154
import com .oracle .truffle .api .interop .UnsupportedMessageException ;
151
155
import com .oracle .truffle .api .library .CachedLibrary ;
152
156
import com .oracle .truffle .api .nodes .LanguageInfo ;
157
+ import com .oracle .truffle .api .nodes .Node ;
153
158
import com .oracle .truffle .api .nodes .NodeUtil ;
154
159
import com .oracle .truffle .api .nodes .RootNode ;
155
160
import com .oracle .truffle .api .source .Source ;
@@ -631,14 +636,62 @@ protected Object getToolPath(TruffleString tool) {
631
636
}
632
637
}
633
638
634
- // Equivalent of PyObject_TypeCheck
635
- @ Builtin (name = "type_check" , minNumOfPositionalArgs = 2 )
639
+ @ Builtin (name = "determine_system_toolchain" , maxNumOfPositionalArgs = 1 )
636
640
@ GenerateNodeFactory
637
- public abstract static class TypeCheckNode extends PythonBinaryBuiltinNode {
641
+ public abstract static class DetermineSystemToolchain extends PythonUnaryBuiltinNode {
642
+ /**
643
+ * This is derived from {@code distutils.unixccompiler._is_gcc}
644
+ */
645
+ private static final String [] C_COMPILER_PRECEDENCE = {"gcc" , "clang" };
646
+ private static final String [] CXX_COMPILER_PRECEDENCE = {"g++" , "clang++" };
647
+
648
+ private static final PKeyword [] GENERIC_TOOLCHAIN = {
649
+ new PKeyword (tsLiteral ("CC" ), tsLiteral ("cc" )),
650
+ new PKeyword (tsLiteral ("CXX" ), tsLiteral ("c++" )),
651
+ new PKeyword (tsLiteral ("AR" ), tsLiteral ("ar" )),
652
+ new PKeyword (tsLiteral ("RANLIB" ), tsLiteral ("ranlib" )),
653
+ new PKeyword (tsLiteral ("LD" ), tsLiteral ("ld" )),
654
+ new PKeyword (tsLiteral ("NM" ), tsLiteral ("nm" ))
655
+ };
656
+
638
657
@ Specialization
639
- boolean typeCheck (Object instance , Object cls ,
640
- @ Cached PyObjectTypeCheck typeCheckNode ) {
641
- return typeCheckNode .execute (instance , cls );
658
+ PDict doGeneric (@ SuppressWarnings ("unused" ) Object unused ) {
659
+ return factory ().createDict (fromToolchain ());
660
+ }
661
+
662
+ @ TruffleBoundary
663
+ private static PKeyword [] fromToolchain () {
664
+ PKeyword [] result = GENERIC_TOOLCHAIN ;
665
+ int id = which ();
666
+ if (id >= 0 ) {
667
+ assert id < C_COMPILER_PRECEDENCE .length ;
668
+ result = Arrays .copyOf (GENERIC_TOOLCHAIN , GENERIC_TOOLCHAIN .length );
669
+ result [0 ] = new PKeyword (tsLiteral ("CC" ), tsLiteral (C_COMPILER_PRECEDENCE [id ]));
670
+ result [1 ] = new PKeyword (tsLiteral ("CXX" ), tsLiteral (CXX_COMPILER_PRECEDENCE [id ]));
671
+ }
672
+ return result ;
673
+ }
674
+
675
+ private static int which () {
676
+ CompilerAsserts .neverPartOfCompilation ();
677
+ String path = System .getenv ("PATH" );
678
+ if (path != null ) {
679
+ for (int i = 0 ; i < C_COMPILER_PRECEDENCE .length ; i ++) {
680
+ int last = 0 ;
681
+ for (int j = path .indexOf (File .pathSeparatorChar ); j != -1 ; j = path .indexOf (File .pathSeparatorChar , last )) {
682
+ Path resolvedProgramName = Paths .get (path .substring (last , j )).resolve (C_COMPILER_PRECEDENCE [i ]);
683
+ if (Files .isExecutable (resolvedProgramName )) {
684
+ return i ;
685
+ }
686
+ /*
687
+ * next start is the char after the separator because we have "path0:path1"
688
+ * and 'i' points to ':'
689
+ */
690
+ last = j + 1 ;
691
+ }
692
+ }
693
+ }
694
+ return -1 ;
642
695
}
643
696
}
644
697
@@ -662,7 +715,7 @@ static long doIt(@SuppressWarnings("unused") Object dummy) {
662
715
}
663
716
}
664
717
665
- // Internal builtin used for testing: changes strategy of newly allocated set or map
718
+ // Internal builtin used for testing: changes strategy of newly allocated set or map
666
719
@ Builtin (name = "set_storage_strategy" , minNumOfPositionalArgs = 2 )
667
720
@ GenerateNodeFactory
668
721
public abstract static class SetStorageStrategyNode extends PythonBinaryBuiltinNode {
0 commit comments