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

InputAST
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؛ يتم تحليل الاستدعاءات المتسلسلة كاستدعاء واحد متعدد الوسائط. أخيرًا، تحتوي سلاسل المقارنات على هيكل تعبير خاص بها.

InputAST
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

InputAST
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

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

InputAST
"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

InputAST
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

تدعم جوليا أنواع أرقام أكثر من العديد من تطبيقات السكيم، لذا لا يتم تمثيل جميع الأرقام مباشرة كأرقام سكيم في شجرة التحليل.

InputAST
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 على QuoteNode whose value field is the symbol a، من أجل إرجاع الرمز نفسه بدلاً من تقييمه.

  • 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]

      اسم الـ struct

    • args[2]

      تعبير call الذي ينشئ SimpleVector مع تحديد معاييره

    • args[3]

      تعبير call الذي ينشئ SimpleVector يحدد أسماء حقوله

    • args[4]

      رمز، مرجع عالمي، أو تعبير يحدد النوع الفائق (على سبيل المثال، :عدد صحيح، مرجع عالمي(النواة، :أي)، أو :(النواة.تطبيق_النوع(المصفوفة_الأساسية، T، N))

    • args[5]

      تعبير call الذي ينشئ SimpleVector يحدد أنواع حقوله

    • args[6]

      قيمة منطقية، صحيحة إذا كانت mutable

    • args[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 دالة من الدرجة الأولى، ومن هنا جاء الاسم.

  • isdefined

    Expr(: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

  • def

    MethodInstance الذي تم اشتقاق هذه الإدخال من ذاكرة التخزين المؤقت.

  • مالك

    رمز يمثل مالك هذا CodeInstance. سيتم استخدام jl_egal للمطابقة.

  • rettype/rettype_const

    نوع الإرجاع المستنتج لحقل specFunctionObject، والذي (في معظم الحالات) هو أيضًا نوع الإرجاع المحسوب للدالة بشكل عام.

  • استنتج

    قد يحتوي على ذاكرة مؤقتة للمصدر المستنتج لهذه الدالة، أو يمكن تعيينه إلى nothing للإشارة فقط إلى أن rettype مستنتج.

  • ftpr

    نقطة الدخول العامة jlcall.

  • jlcall_api

    الـ ABI الذي يجب استخدامه عند استدعاء fptr. بعض الأجزاء المهمة تشمل:

    • 0 - لم يتم تجميعه بعد
    • 1 - JL_CALLABLE jl_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 لمزيد من التفاصيل.