Julia ASTs
تحتوي جوليا على تمثيلين من الشيفرة. أولاً، هناك شجرة التركيب السطحية (AST) التي يتم إرجاعها بواسطة المحلل (على سبيل المثال، دالة Meta.parse)، ويتم التلاعب بها بواسطة الماكرو. إنها تمثيل منظم للشيفرة كما هو مكتوب، يتم بناؤه بواسطة julia-parser.scm من تدفق الأحرف. بعد ذلك، هناك شكل مخفض، أو IR (تمثيل وسيط)، والذي يستخدمه استنتاج الأنواع وتوليد الشيفرة. في الشكل المخفض، هناك أنواع أقل من العقد، يتم توسيع جميع الماكرو، ويتم تحويل جميع تدفقات التحكم إلى فروع صريحة وتسلسلات من العبارات. يتم بناء الشكل المخفض بواسطة julia-syntax.scm.
أولاً سنركز على AST، لأنه مطلوب لكتابة الماكروهات.
Surface syntax AST
تتكون أشجار التركيب الأمامية (ASTs) تقريبًا بالكامل من Expr والذرات (مثل الرموز، الأرقام). عمومًا، هناك رأس تعبير مختلف لكل شكل نحوي متميز بصريًا. سيتم تقديم أمثلة بصيغة s-expression. كل قائمة محاطة بأقواس تتوافق مع Expr، حيث العنصر الأول هو الرأس. على سبيل المثال، (call f x) تتوافق مع Expr(:call, :f, :x) في جوليا.
Calls
| Input | AST |
|---|---|
f(x) | (call f x) |
f(x, y=1, z=2) | (call f x (kw y 1) (kw z 2)) |
f(x; y=1) | (call f (parameters (kw y 1)) x) |
f(x...) | (call f (... x)) |
do بناء الجملة:
f(x) do a,b
body
endيتم تحليله كـ (do (call f x) (-> (tuple a b) (block body))).
Operators
تستخدم معظم العمليات كاستدعاءات دوال، لذا يتم تحليلها برأس call. ومع ذلك، فإن بعض العمليات هي أشكال خاصة (ليست بالضرورة استدعاءات دوال)، وفي هذه الحالات يكون المشغل نفسه هو رأس التعبير. في julia-parser.scm، يُشار إلى هذه العمليات باسم "المشغلين النحويين". تستخدم بعض العمليات (+ و *) تحليل N-ary؛ يتم تحليل الاستدعاءات المتسلسلة كاستدعاء واحد متعدد الوسائط. أخيرًا، تحتوي سلاسل المقارنات على هيكل تعبير خاص بها.
| Input | AST |
|---|---|
x+y | (call + x y) |
a+b+c+d | (call + a b c d) |
2x | (call * 2 x) |
a&&b | (&& a b) |
x += 1 | (+= x 1) |
a ? 1 : 2 | (if a 1 2) |
a,b | (tuple a b) |
a==b | (call == a b) |
1<i<=n | (comparison 1 < i <= n) |
a.b | (. a (quote b)) |
a.(b) | (. a (tuple b)) |
Bracketed forms
| Input | AST |
|---|---|
a[i] | (ref a i) |
t[i;j] | (typed_vcat t i j) |
t[i j] | (typed_hcat t i j) |
t[a b; c d] | (typed_vcat t (row a b) (row c d)) |
t[a b;;; c d] | (typed_ncat t 3 (row a b) (row c d)) |
a{b} | (curly a b) |
a{b;c} | (curly a (parameters c) b) |
[x] | (vect x) |
[x,y] | (vect x y) |
[x;y] | (vcat x y) |
[x y] | (hcat x y) |
[x y; z t] | (vcat (row x y) (row z t)) |
[x;y;; z;t;;;] | (ncat 3 (nrow 2 (nrow 1 x y) (nrow 1 z t))) |
[x for y in z, a in b] | (comprehension (generator x (= y z) (= a b))) |
T[x for y in z] | (typed_comprehension T (generator x (= y z))) |
(a, b, c) | (tuple a b c) |
(a; b; c) | (block a b c) |
Macros
| Input | AST |
|---|---|
@m x y | (macrocall @m (line) x y) |
Base.@m x y | (macrocall (. Base (quote @m)) (line) x y) |
@Base.m x y | (macrocall (. Base (quote @m)) (line) x y) |
Strings
| Input | AST |
|---|---|
"a" | "a" |
x"y" | (macrocall @x_str (line) "y") |
x"y"z | (macrocall @x_str (line) "y" "z") |
"x = $x" | (string "x = " x) |
`a b c` | (macrocall @cmd (line) "a b c") |
صيغة سلسلة الوثائق:
"some docs"
f(x) = xيتم تحليله كـ (macrocall (|.| Core '@doc) (line) "بعض الوثائق" (= (call f x) (block x))).
Imports and such
| Input | AST |
|---|---|
import a | (import (. a)) |
import a.b.c | (import (. a b c)) |
import ...a | (import (. . . . a)) |
import a.b, c.d | (import (. a b) (. c d)) |
import Base: x | (import (: (. Base) (. x))) |
import Base: x, y | (import (: (. Base) (. x) (. y))) |
export a, b | (export a b) |
using له نفس التمثيل مثل import، ولكن مع رأس التعبير :using بدلاً من :import.
Numbers
تدعم جوليا أنواع أرقام أكثر من العديد من تطبيقات السكيم، لذا لا يتم تمثيل جميع الأرقام مباشرة كأرقام سكيم في شجرة التحليل.
| Input | AST |
|---|---|
11111111111111111111 | (macrocall @int128_str nothing "11111111111111111111") |
0xfffffffffffffffff | (macrocall @uint128_str nothing "0xfffffffffffffffff") |
1111...many digits... | (macrocall @big_str nothing "1111....") |
Block forms
يتم تحليل كتلة من العبارات على أنها (block stmt1 stmt2 ...).
إذا كانت العبارة:
if a
b
elseif c
d
else
e
endيتم تحليلها كـ:
(if a (block (line 2) b)
(elseif (block (line 3) c) (block (line 4) d)
(block (line 6 e))))حلقة while تُحلل على أنها (while الشرط الجسم).
حلقة for تُحلل على أنها (for (= var iter) body). إذا كان هناك أكثر من مواصفة تكرار، فإنها تُحلل ككتلة: (for (block (= v1 iter1) (= v2 iter2)) body).
break و continue يتم تحليلهما كتعابير ذات 0 حجة (break) و (continue).
let يتم تحليله كـ (let (= var val) body) أو (let (block (= var1 val1) (= var2 val2) ...) body)، مثل حلقات for.
تعريف دالة أساسي يتم تحليله على أنه (function (call f x) body). مثال أكثر تعقيدًا:
function f(x::T; k = 1) where T
return x+1
endيتم تحليله كالتالي:
(function (where (call f (parameters (kw k 1))
(:: x T))
T)
(block (line 2) (return (call + x 1))))تعريف النوع:
mutable struct Foo{T<:S}
x::T
endيتم تحليلها كـ:
(struct true (curly Foo (<: T S))
(block (line 2) (:: x T)))الحجة الأولى هي قيمة منطقية تخبر ما إذا كان النوع قابلًا للتغيير.
try الكتل يتم تحليلها كـ (try try_block var catch_block finally_block). إذا لم يكن هناك متغير موجود بعد catch، فإن var هو #f. إذا لم يكن هناك عبارة finally، فإن الحجة الأخيرة غير موجودة.
Quote expressions
تدعم أشكال بناء جملة مصدر جوليا لاقتباس الشيفرة (quote و :( )) الاستبدال باستخدام $. في مصطلحات ليسب، هذا يعني أنها في الواقع أشكال "backquote" أو "quasiquote". داخليًا، هناك أيضًا حاجة لاقتباس الشيفرة بدون استبدال. في شيفرة جوليا، يتم تمثيل الاقتباس غير المستبدل برأس التعبير inert.
تتحول التعبيرات inert إلى كائنات QuoteNode في جوليا. تقوم هذه الكائنات بتغليف قيمة واحدة من أي نوع، وعند تقييمها تعيد ببساطة تلك القيمة.
تعبير quote الذي تكون حجته ذرة يتم تحويله أيضًا إلى QuoteNode.
Line numbers
معلومات موقع المصدر تمثل كـ (line line_num file_name) حيث أن المكون الثالث اختياري (ويتم حذفه عندما يتغير رقم السطر الحالي، ولكن ليس اسم الملف).
تمثل هذه التعبيرات كـ LineNumberNodes في جوليا.
Macros
تمثل نظافة الماكرو من خلال التعبير escape و hygienic-scope. يتم تلقائيًا لف نتيجة توسيع الماكرو في (hygienic-scope block module)، لتمثيل نتيجة النطاق الجديد. يمكن للمستخدم إدراج (escape block) داخلها لدمج الشيفرة من المتصل.
Lowered form
الصيغة المنخفضة (IR) أكثر أهمية للمترجم، حيث تُستخدم لاستنتاج الأنواع، والتحسينات مثل الإدراج، وتوليد الشيفرة. كما أنها أقل وضوحًا للإنسان، حيث إنها ناتجة عن إعادة ترتيب كبيرة لمدخلات الصياغة.
بالإضافة إلى Symbols وبعض أنواع الأرقام، توجد الأنواع التالية من البيانات في شكل مخفض:
Exprلديه نوع عقدة يشير إليه حقل
head، وحقلargsالذي هوVector{Any}من التعبيرات الفرعية. بينما يتم تمثيل كل جزء تقريبًا من شجرة التركيب السطحية بواسطةExpr، فإن IR يستخدم عددًا محدودًا فقط منExprs، في الغالب للمكالمات وبعض الأشكال التي تكون فقط على المستوى الأعلى.رقم الفتحةيحدد المعاملات والمتغيرات المحلية عن طريق الترقيم المتسلسل. يحتوي على حقل
idذو قيمة صحيحة يعطي فهرس الفتحة. يمكن العثور على أنواع هذه الفتحات في حقلslottypesمن كائنCodeInfoالخاص بهم.حجةنفس الشيء مثل
SlotNumber، ولكنه يظهر فقط بعد التحسين. يشير إلى أن الفتحة المشار إليها هي حجة للدالة المحيطة.معلومات_الكوديلف IR لمجموعة من العبارات. حقل
codeهو مصفوفة من التعبيرات للتنفيذ.GotoNodeفرع غير مشروط. الحجة هي هدف الفرع، الممثل كفهرس في مصفوفة الشيفرة للقفز إليه.
GotoIfNotفرع شرطي. إذا كانت قيمة حقل
condتساوي خطأ، ينتقل إلى الفهرس المحدد بواسطة حقلdest.ReturnNodeيعيد وسيطه (حقل
val) كقيمة للدالة المحيطة. إذا كان حقلvalغير معرف، فإن هذا يمثل عبارة غير قابلة للوصول.QuoteNodeيلف قيمة عشوائية للإشارة إليها كبيانات. على سبيل المثال، تحتوي الدالة
f() = :aعلىQuoteNodewhosevaluefield is the symbola، من أجل إرجاع الرمز نفسه بدلاً من تقييمه.GlobalRefتشير إلى المتغير العالمي
nameفي الوحدةmod.SSAValueيشير إلى متغير تعيين ثابت (SSA) مرقم بالتتابع (يبدأ من 1) تم إدخاله بواسطة المترجم. الرقم (
id) لـSSAValueهو فهرس مصفوفة الشيفرة للتعبير الذي يمثل قيمته.NewvarNodeيحدد نقطة يتم فيها إنشاء متغير (فتحة). هذا له تأثير إعادة تعيين المتغير إلى غير معرف.
Expr types
تظهر هذه الرموز في حقل head من Expr بشكل مخفض.
callاستدعاء الدالة (التوجيه الديناميكي).
args[1]هي الدالة التي سيتم استدعاؤها، وargs[2:end]هي المعاملات.استدعاءاستدعاء الدالة (الإرسال الثابت).
args[1]هو MethodInstance الذي سيتم استدعاؤه، وargs[2:end]هي المعاملات (بما في ذلك الدالة التي يتم استدعاؤها، فيargs[2]).static_parameterالإشارة إلى معلمة ثابتة بواسطة الفهرس.
=التكليف. في IR، الحجة الأولى دائمًا هي
SlotNumberأوGlobalRef.طريقةيضيف طريقة إلى دالة عامة ويعين النتيجة إذا لزم الأمر.
لديه شكل ذو حجة واحدة وشكل ذو ثلاث حجج. الشكل ذو الحجة الواحدة ينشأ من بناء الجملة
function foo end. في الشكل ذو الحجة الواحدة، الحجة هي رمز. إذا كان هذا الرمز يسمي بالفعل دالة في النطاق الحالي، فلا يحدث شيء. إذا كان الرمز غير معرف، يتم إنشاء دالة جديدة وتعيينها إلى المعرف المحدد بواسطة الرمز. إذا كان الرمز معرفًا ولكنه يسمي شيئًا غير دالة، يتم رفع خطأ. تعريف "يسمي دالة" هو أن الربط ثابت، ويشير إلى كائن من نوع فردي. السبب في ذلك هو أن مثيلًا من نوع فردي يحدد بشكل فريد النوع الذي سيتم إضافة الطريقة إليه. عندما يحتوي النوع على حقول، لن يكون من الواضح ما إذا كانت الطريقة تتم إضافتها إلى المثيل أو إلى نوعه.تحتوي صيغة الثلاثة معطيات على المعطيات التالية:
args[1]اسم الدالة، أو
nothingإذا كان غير معروف أو غير ضروري. إذا كان رمزًا، فإن التعبير يتصرف أولاً مثل الشكل ذو الحجة الواحدة أعلاه. يتم تجاهل هذه الحجة من تلك النقطة فصاعدًا. يمكن أن يكونnothingعندما تتم إضافة الطرق بشكل صارم حسب النوع،(::T)(x) = x، أو عندما يتم إضافة طريقة إلى دالة موجودة،MyModule.f(x) = x.args[2]SimpleVectorمن نوع البيانات.args[2][1]هوSimpleVectorمن أنواع المعاملات، وargs[2][2]هوSimpleVectorمن متغيرات النوع المقابلة للمعلمات الثابتة للطريقة.args[3]CodeInfoلطريقة نفسها. بالنسبة لتعريفات الطرق "خارج النطاق" (إضافة طريقة إلى دالة تحتوي أيضًا على طرق معرفة في نطاقات مختلفة) هذه تعبير يقيم إلى تعبير:lambda.
struct_typeتعبير مكون من 7 معطيات يعرف
structجديدة:args[1]اسم الـ
structargs[2]تعبير
callالذي ينشئSimpleVectorمع تحديد معاييرهargs[3]تعبير
callالذي ينشئSimpleVectorيحدد أسماء حقولهargs[4]رمز،مرجع عالمي، أوتعبيريحدد النوع الفائق (على سبيل المثال،:عدد صحيح،مرجع عالمي(النواة، :أي)، أو:(النواة.تطبيق_النوع(المصفوفة_الأساسية، T، N))args[5]تعبير
callالذي ينشئSimpleVectorيحدد أنواع حقولهargs[6]قيمة منطقية، صحيحة إذا كانت
mutableargs[7]عدد المعاملات للتهيئة. سيكون هذا هو عدد الحقول، أو الحد الأدنى من عدد الحقول التي يتم استدعاؤها بواسطة عبارة
newلمُنشئ داخلي.
abstract_typeتعبير ذو 3 معطيات يحدد نوعًا مجردًا جديدًا. المعطيات هي نفسها المعطيات 1 و2 و4 من تعبيرات
struct_type.نوع_بدائيتعبير ذو 4 معطيات يحدد نوعًا بدائيًا جديدًا. المعطيات 1 و2 و4 هي نفسها
struct_type. المعطى 3 هو عدد البتات.Julia 1.5 تمت إزالة
struct_typeوabstract_typeوprimitive_typeفي Julia 1.5 واستُبدلت باستدعاءات إلى دوال جديدة.عالمييعلن عن ارتباط عالمي.
constيعلن عن متغير (عالمي) كثابت.
جديديخصص كائنًا جديدًا يشبه الهيكل. الحجة الأولى هي النوع. يتم تقليل الدالة الزائفة
newإلى هذا، ويتم إدراج النوع دائمًا بواسطة المترجم. هذه ميزة داخلية بحتة، ولا تقوم بأي تحقق. يمكن أن يؤدي تقييم تعبيراتnewعشوائية إلى حدوث خطأ في الوصول إلى الذاكرة.splatnewمماثل لـ
new، باستثناء أن قيم الحقول تُمرر كـ tuple واحدة. يعمل بشكل مشابه لـsplat(new)إذا كانتnewدالة من الدرجة الأولى، ومن هنا جاء الاسم.isdefinedExpr(:isdefined, :x)يُرجع قيمة Bool تشير إلى ما إذا كانxقد تم تعريفه بالفعل في النطاق الحالي.الاستثناءيُعيد الاستثناء الذي تم التقاطه داخل كتلة
catch، كما يتم إرجاعه بواسطةjl_current_exception(ct).enterيدخل معالج الاستثناءات (
setjmp).args[1]هو تسمية كتلة الالتقاط التي يتم القفز إليها عند حدوث خطأ. ينتج رمزًا يتم استهلاكه بواسطةpop_exception.تركقم بإزالة معالجات الاستثناء.
args[1]هو عدد المعالجات التي يجب إزالتها.pop_exceptionقم بإرجاع مكدس الاستثناءات الحالي إلى الحالة المرتبطة بـ
enterعند مغادرة كتلة catch. تحتويargs[1]على الرمز المميز منenterالمرتبط.Julia 1.1 pop_exceptionجديد في جوليا 1.1.inboundsيتحكم في تشغيل أو إيقاف فحوصات الحدود. يتم الحفاظ على مكدس؛ إذا كانت الحجة الأولى لهذه التعبير صحيحة أو خاطئة (
trueتعني أن فحوصات الحدود معطلة)، يتم دفعها إلى المكدس. إذا كانت الحجة الأولى هي:pop، يتم إزالة العنصر من المكدس.boundscheckلديه القيمة
falseإذا تم تضمينه في قسم من الشيفرة الموسومة بـ@inbounds، وإلا فإن له القيمةtrue.loopinfoيحدد نهاية الحلقة. يحتوي على بيانات وصفية يتم تمريرها إلى
LowerSimdLoopإما لتحديد الحلقة الداخلية لتعبير@simd، أو لنقل المعلومات إلى تمريرات حلقة LLVM.copyastجزء من تنفيذ الاقتباس شبه. الحجة هي شجرة تركيب بناء الجملة السطحية التي يتم نسخها ببساطة بشكل متكرر وإرجاعها في وقت التشغيل.
ميتابيانات التعريف.
args[1]عادة ما يكون رمزًا يحدد نوع بيانات التعريف، وبقية المعاملات تكون بشكل حر. الأنواع التالية من بيانات التعريف تُستخدم عادة::inlineو:noinline: تلميحات الإدراج.
foreigncallحاوية محسوبة ثابتة لمعلومات
ccall. الحقول هي:args[1]: الاسمالتعبير الذي سيتم تحليله لوظيفة خارجية.
args[2]::Type: RTنوع الإرجاع (الحرفي)، يتم حسابه بشكل ثابت عند تعريف الطريقة المحتوية.
args[3]::SimpleVector(of Types) : ATالمتجه (الحرفي) لأنواع الوسائط، الذي يتم حسابه بشكل ثابت عند تعريف الطريقة المحتوية.
args[4]::Int: nreqعدد المعاملات المطلوبة لتعريف دالة varargs.
args[5]::QuoteNode{Symbol}: اتفاقية الاستدعاءاتفاقية الاستدعاء للمكالمة.
args[6:5+length(args[3])]: الحججالقيم لجميع المعاملات (مع أنواع كل منها المعطاة في args[3]).
args[6+length(args[3])+1:end]: جذور gcالأشياء الإضافية التي قد تحتاج إلى أن تكون gc-rooted طوال مدة الاستدعاء. انظر Working with LLVM لمعرفة من أين تم اشتقاق هذه الأشياء وكيف يتم التعامل معها.
new_opaque_closureينشئ إغلاقًا غير شفاف جديدًا. الحقول هي:
args[1]: التوقيعتوقيع دالة الإغلاق غير الشفاف. لا تشارك الإغلاقات غير الشفافة في التوزيع، ولكن يمكن تقييد أنواع المدخلات.
args[2]: isvaيشير إلى ما إذا كانت الإغلاق تقبل varargs.
args[3]: lbحد أدنى على نوع الإخراج. (الإعدادات الافتراضية هي
Union{})args[4]: ubحد أعلى على نوع الإخراج. (الإعدادات الافتراضية هي
Any)args[5]: طريقةالطريقة الفعلية كتعبيرة
opaque_closure_method.args[6:end]: يلتقطالقيم الملتقطة بواسطة الإغلاق غير الشفاف.
Julia 1.7 تمت إضافة الإغلاقات غير الشفافة في جوليا 1.7
Method
حاوية فريدة تصف البيانات الوصفية المشتركة لطريقة واحدة.
name،module،file،line،sigبيانات التعريف لتحديد الطريقة بشكل فريد للكمبيوتر والإنسان.
ambigذاكرة الطرق الأخرى التي قد تكون غامضة مع هذه.
التخصصاتذاكرة مؤقتة لجميع مثيلات MethodInstance التي تم إنشاؤها لهذا الأسلوب، تُستخدم لضمان التفرد. التفرد مطلوب من أجل الكفاءة، خاصةً من أجل التجميع المسبق التزايدي وتتبع إبطال الأسلوب.
المصدرالكود المصدر الأصلي (إذا كان متاحًا، عادةً ما يكون مضغوطًا).
مولدكائن قابل للاستدعاء يمكن تنفيذه للحصول على مصدر متخصص لتوقيع طريقة محددة.
الجذورمؤشرات إلى أشياء غير AST تم إدخالها في AST، المطلوبة لضغط AST، استنتاج النوع، أو توليد الشيفرة الأصلية.
nargs،isva،called،is_for_opaque_closure،حقول بت وصفية لشفرة المصدر لهذه الطريقة.
primary_worldعصر العالم الذي "يمتلك" هذه الطريقة.
MethodInstance
حاوية فريدة تصف توقيعًا قابلًا للاستدعاء لطريقة واحدة. انظر بشكل خاص إلى Proper maintenance and care of multi-threading locks للحصول على تفاصيل مهمة حول كيفية تعديل هذه الحقول بأمان.
specTypesالمفتاح الأساسي لهذه MethodInstance. يتم ضمان التفرد من خلال بحث
def.specializations.defالـ
Methodالذي تصفه هذه الدالة هو تخصص لـ. أوModule، إذا كانت هذه دالة Lambda على مستوى أعلى تم توسيعها في Module، وليست جزءًا من Method.sparam_valsقيم المعلمات الثابتة في
specTypes. بالنسبة لـMethodInstanceفيMethod.unspecialized، تكون هذه هيSimpleVectorالفارغة. ولكن بالنسبة لـMethodInstanceفي وقت التشغيل من ذاكرة التخزين المؤقت لـMethodTable، ستكون هذه دائمًا معرفة وقابلة للفهرسة.uninferredشفرة المصدر غير المضغوطة لثانك على المستوى الأعلى. بالإضافة إلى ذلك، بالنسبة لدالة تم إنشاؤها، هذا هو أحد العديد من الأماكن التي قد توجد فيها شفرة المصدر.
backedgesنحن نخزن قائمة عكسية من تبعيات التخزين المؤقت لتتبع فعال للعملية المتزايدة لإعادة التحليل / إعادة الترجمة التي قد تكون مطلوبة بعد تعريفات طرق جديدة. يعمل هذا من خلال الاحتفاظ بقائمة من
MethodInstanceالأخرى التي تم استنتاجها أو تحسينها لتحتوي على استدعاء محتمل لهذهMethodInstance. قد يتم تخزين نتائج التحسين تلك في مكان ما فيcache، أو قد تكون نتيجة لشيء لم نرغب في تخزينه، مثل انتشار الثوابت. وبالتالي، نقوم بدمج جميع تلك الحواف الخلفية إلى إدخالات التخزين المؤقت المختلفة هنا (هناك دائمًا تقريبًا إدخال تخزين مؤقت واحد قابل للتطبيق مع قيمة sentinel لـ max_world على أي حال).ذاكرة التخزين المؤقتذاكرة مؤقتة لكائنات
CodeInstanceالتي تشترك في هذا التهيئة للقالب.
CodeInstance
defMethodInstanceالذي تم اشتقاق هذه الإدخال من ذاكرة التخزين المؤقت.مالكرمز يمثل مالك هذا
CodeInstance. سيتم استخدامjl_egalللمطابقة.rettype/rettype_constنوع الإرجاع المستنتج لحقل
specFunctionObject، والذي (في معظم الحالات) هو أيضًا نوع الإرجاع المحسوب للدالة بشكل عام.استنتجقد يحتوي على ذاكرة مؤقتة للمصدر المستنتج لهذه الدالة، أو يمكن تعيينه إلى
nothingللإشارة فقط إلى أنrettypeمستنتج.ftprنقطة الدخول العامة jlcall.
jlcall_apiالـ ABI الذي يجب استخدامه عند استدعاء
fptr. بعض الأجزاء المهمة تشمل:- 0 - لم يتم تجميعه بعد
- 1 -
JL_CALLABLEjl_value_t *(*)(jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs) - 2 - ثابت (القيمة المخزنة في
rettype_const) - 3 - مع تمرير المعلمات الثابتة
jl_value_t *(*)(jl_svec_t *sparams, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs) - 4 - تشغيل في المفسر
jl_value_t *(*)(jl_method_instance_t *meth, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)
min_world/max_worldنطاق أعمار العالم التي يمكن استدعاء هذه الحالة منها. إذا كانت max_world هي قيمة الرمز الخاص
-1، فإن القيمة غير معروفة بعد. يمكن الاستمرار في استخدامها حتى نواجه حافة خلفية تتطلب منا إعادة النظر.
CodeInfo
حاوية (عادة مؤقتة) لحفظ كود المصدر المنخفض.
كودمصفوفة
Anyمن العباراتslotnamesمصفوفة من الرموز تعطي أسماء لكل فتحة (وسيط أو متغير محلي).
slotflagsمصفوفة
UInt8من خصائص الفتحات، ممثلة كأعلام بت:- 0x02 - مُعين (فقط يكون خطأ إذا لم يكن هناك أي عبارات تعيين مع هذه المتغير على اليسار)
- 0x08 - مستخدم (إذا كان هناك أي قراءة أو كتابة للفتحة)
- 0x10 - مُعَيَّنَة بشكل ثابت مرة واحدة
- 0x20 - قد يتم استخدامه قبل التعيين. هذه العلامة صالحة فقط بعد استنتاج النوع.
ssavaluetypesإما مصفوفة أو
Int.إذا كان
Int، فإنه يعطي عدد المواقع المؤقتة المدخلة بواسطة المترجم في الدالة (طول مصفوفةcode). إذا كانت مصفوفة، فإنها تحدد نوعًا لكل موقع.ssaflagsعلامات 32 بت على مستوى العبارة لكل تعبير في الدالة. راجع تعريف
jl_code_info_tفي julia.h لمزيد من التفاصيل.linetableمصفوفة من كائنات مواقع المصدر
codelocsمصفوفة من مؤشرات الأعداد الصحيحة إلى
linetable، تعطي الموقع المرتبط بكل عبارة.
حقول اختيارية:
أنواع الفتحاتمصفوفة من الأنواع للفجوات.
rettypeنوع الإرجاع المستنتج للشكل المنخفض (IR). القيمة الافتراضية هي
Any.method_for_inference_limit_heuristicsستقوم
method_for_inference_heuristicsبتوسيع مولد الطريقة المعطاة إذا لزم الأمر أثناء الاستدلال.الأبMethodInstanceالذي "يمتلك" هذا الكائن (إذا كان ذلك مناسبًا).الحوافقم بإعادة توجيه الحواف إلى مثيلات الطرق التي يجب إبطالها.
min_world/max_worldنطاق أعمار العالم الذي كان هذا الرمز صالحًا له في الوقت الذي تم استنتاجه فيه.
خصائص بوليانية:
استنتجسواء كان هذا قد تم إنتاجه بواسطة استنتاج النوع.
inlineableسواء كان يجب أن يكون هذا مؤهلاً للتضمين.
propagate_inboundsسواء كان يجب أن ينشر
@inboundsعند تضمينه لغرض حذف كتل@boundscheck.
إعدادات UInt8:
constprop- 0 = استخدم القاعدة التجريبية
- 1 = عدواني
- 2 = لا شيء
النقاءمُكون من 5 علامات بت:- 0x01 << 0 = هذه الطريقة مضمونة لإرجاع أو إنهاء بشكل متسق (
:consistent) - 0x01 << 1 = هذه الطريقة خالية من الآثار الجانبية المرئية دلاليًا من الخارج (
:effect_free) - 0x01 << 2 = هذه الطريقة مضمونة لعدم إلقاء استثناء (
:nothrow) - 0x01 << 3 = هذه الطريقة مضمونة لإنهاء (
:terminates_globally) - 0x01 << 4 = التحكم في تدفق التركيب داخل هذه الطريقة مضمون أن ينتهي (
:terminates_locally)
راجع الوثائق الخاصة بـ
Base.@assume_effectsلمزيد من التفاصيل.- 0x01 << 0 = هذه الطريقة مضمونة لإرجاع أو إنهاء بشكل متسق (