Programming Parrot Dan Sugalski [email protected]. Important safety tips! Parrot has no safety net You...

68
Programming Parrot Dan Sugalski dan @ sidhe .org

Transcript of Programming Parrot Dan Sugalski [email protected]. Important safety tips! Parrot has no safety net You...

Important safety tips!Important safety tips!

• Parrot has no safety net• You can crash pretty easily• Parrot’s not entirely bug-free• All the ops are documented• perldoc ops/file.ops• (Knowing the right file can be

interesting)

PASM & PIRPASM & PIR

• PASM - Parrot assembly• PIR - Parrot Intermediate

Representation• PASM is simple• PIR is convenient• Mix and match across files

Standard extensionsStandard extensions

• .pasm - Parrot assembly• .imc - Parrot intermediate

representation• .pbc - Parrot bytecode

Invoking ParrotInvoking Parrot

• parrot foo.pbc• parrot -o foo.pbc foo.imc• parrot -o foo.pbc foo.pasm• parrot foo.pasm• parrot foo.imc• parrot -o foo.pasm foo.imc

Extension autodetectExtension autodetect

• Source automatically compiled and run

• Input type based on extension• Output type based on extension• No automatic decompilation,

though

PASMPASM

• Implicit main routine• Everything manual• Simple• No help from parrot

PIRPIR

• Compilation units required• Infinite register store• Calling convention shortcuts

Behold, the opcpdeBehold, the opcpde

• opname [dest,] [source[, source…]]

• add I2, I3, I4• print “some thing\n”• PIR shortcut:

dest = op source1, source2

same asop dest, source1, source2

Hello, world!Hello, world!

print “Hello, PASM world!\n”end

Hello, world!Hello, world!

.sub foo @MAINprint “Hello, PIR world!\n”end

.end

All PIR from here on out

ConstantsConstants

• Signed integer constants• Floating point constants• Single or double quoted string

constants• Standard string backslash escapes

apply

Named constantsNamed constants

.const type name = value

.const int five = 5

.const str error = “Don’t do that!”• Constants are scoped to the

compilation unit

Include filesInclude files

.include “filename”• Includes the file as if it were right

there• Nothing fancy• No path searching right now

Defining SubroutinesDefining Subroutines

.sub sub_nameSub body here

.end

Subroutine propertiesSubroutine properties

• Go after sub name, comma-separated• method, prototyped, @LOAD, @MAIN• method - self filled in with calling object• prototyped - takes or returns non-PMCs• @MAIN - main sub for bytecode file• @LOAD - sub to execute on bytecode

load

Virtual RegistersVirtual Registers

• Sub-local• $In, $Pn, $Nn, $Sn• Assembler auto-spills for you

Basic MathBasic Math

• add, sub, mul, div• mod and cmod• inc and dec• Transcendental math• Docs: ops/math.ops

PIR shortcutsPIR shortcuts

• Infix math works• Normal notation works• I3 = I5 + I6• $P6 = $P6 - 5• result = source * 4• C shortcuts work• $P6 += 4

Safety tipSafety tip

• PMC destination generally must exist

• Op docs sayabs(in PMC, in PMC) must existfind_global(out PMC, in STR, in STR)

returned

Creating PMCsCreating PMCs

• new dest, type• dest = new type• Type can be a predefined constant

line = new Integerline = foo + 12

• Undef is a good type for temps (it changes type on first assignment)

Basic PMC typesBasic PMC types

• Boolean• Integer• String• Float• Null• Undef

• Env• FixedtypeArray• ResizeabletypeArr

ay

Finding PMC typesFinding PMC types

• Basic types have predefined constants

• User types can be found with find_type$I4 = find_type ‘String’

• Type of an existing PMC with typeof$I5 = typeof $P5$S5 = typeof $P5

Named tempsNamed temps

.local type name• sub-local• Automatically spilled, just like

virtual registers• PMC locals must still be new’d• Virtual registers don’t

automagically have a valid destination

Basic string opsBasic string ops

• Concatenation:$S4 = concat $S5, $S6

• Repetition$S5 = repeat “ “, 10

• Finding substringoffset = index source, substring[, start]

• String lengthstrlen = length $S103

String length trickyString length tricky

• Bytes, code points, and characters• bytelength, codepointlength,

graphemelength, respectively• length is shortcut for

graphemelength• Part of encoding upgrade in

process

Calling SubroutinesCalling Subroutines

foo()foo(1, 2, $S4, $P5)result = foo(1, 2, 3)(result1, result2) = foo(1, 2, 3)

• Can call a PMC representing a sub, or a sub in the current namespace

• No typechecking!

Returning valuesReturning values

.pcc_begin_return.result xxx

.pcc_end_return• No type checking. Get it right or

find bizarre bugs later

Moving aroundMoving around

• Labels end with a colonexit_spot:

• Labels are sub local• branch goes to a label

branch exit_spot• jump goes to a label too• branch is relative, jump absolute• Use branch

Branch basicsBranch basics

• Branches are relative• 2G offset plus or minus• We’ve not found this to be a

limitation in practice

Tiny subsTiny subs

• bsr branches to a label too• Pushes return address on stack• ret will return from a bsr• Much lighter-weight than a sub call• No calling conventions• Must stay within a sub

Conditional Branch: ifConditional Branch: if

if thing, label• Tests thing for truth, branches if

true• Numbers: 0 is false• Strings: Empty string or string “0”• PMCs: We ask them

Conditional Branch: unlessConditional Branch: unless

unless thing, label• Branch if false

Comparison branchesComparison branches

• eq, ne, lt, gt, ge, le• Same type, or low type and PMC• Each has an _str and _num variant

to force string or numeric comparisons

Existence branchesExistence branches

isnull thing, dest• Used for strings and PMCs• Branches if the register has a NULL

pointer or a Null PMC in it

PIR shortcutsPIR shortcuts

if thing1 op thing2 goto label• Op is <, >, <=, >=, !=, ==• No then in there

Assignment and value setting

Assignment and value setting

• Int and Floats are value types• PMCs and Strings are reference

types• Simple assignment with set

set I5, I6set S4, S6

• Copies contents of register• Aliases PMCs and Strings

Assignment and value setting

Assignment and value setting

• Assign copies the dataassign $P4, $P5

• Calls destination’s set function• Works for strings and PMCs

Cross-type assignmentCross-type assignment

• Source and destination different basic types

• Performs automatic conversion• PIR = does assignment

$S5 = $I5$N5 = $P5

Safety tipSafety tip

• PIR = operator is set$P5 = $P6

• Same asset $P5, $P6

• Not assignment!

Input and outputInput and output

• Basic filehandle-based IO system• Async & event driven under the

hood• (When we get that finished)

OutputOutput

• Simple output with print• Prints any type, as well as

constants• Integers and floats get stringified• PMCs get their __get_string

methods called• To stdout by default• Or provide a filehandle

OutputOutput

print “Hello, world\n”printerr “Hello, error world\n”print some_filehandle, “Hello, filehandle\

n”

InputInput

• Block-oriented reads$S1 = read 10

$S2 = read $P4, 10

• Line-oriented reads$S2 = readline $P4

• Line reads stop at newline or 64k, whichever comes first

Standard filehandlesStandard filehandles

• getstdin, getstdout, getstderr fetch filehandles$P5 = getstdin$S5 = readline $P4

Opening filesOpening files

• Open with open• $P5 = open “filename”, file_mode

• Returns an undef on error• File modes are perl-like:

• >, <, >>, +<, +>• fopen r, w, a, r+, and w+ modes

• Only files right now

File infoFile info

• stat and fstat ops return stat info on files

• stat uses filenames, fstat file numbers$I5 = stat ‘foo.txt’, STAT_FILESIZE$I6 = fstat 2, STAT_FILESIZE

• Constants defined in runtime/parrot/include/stat.pasm

• Both portable and non-portable data there

Global variablesGlobal variables

• Parrot has a hierarchic, unified global variable store

• Each sub has a default namespace• Set with .namespace directive

.namespace [‘Foo’; ‘Bar’]

• Global store only holds PMCs

Fetching globalsFetching globals

• Fetch with find_global$P6 = find_global ‘globalname’$P6 = find_global [‘foo’; ‘bar’], ‘globalname’

• Fetches a pointer!• Changes to PMC will be changed in

global store• Throws exception on failure

Storing GlobalsStoring Globals

• Store with store_globalstore_global ‘name’, $P5store_global [‘foo’; ‘bar’], ‘varname’,

$P5

• Overwrites whatever was there• Not an assignment

ClassesClasses

• Simple slot-based object system• Actively instantiated• Multiple inheritance• No metaclasses (yet)

Creating a classCreating a class

• New base class uses newclassclass_pmc = newclass ‘classname’

• Subclass with subclassnew_class = subclass ‘parent’, ‘classname’new_class = subclass class_pmc, ‘classname’anon_class = subclass ‘classname’anon_class = subclass class_pmc

Modifying a classModifying a class

• Add a parent class with addparentaddparent my_class, new_parent

• Remove a parent class with removeparentremoveparent my_class, gone_parent

• Add an attribute with addattributeaddattribute class_pmc, ‘attrib_name’

Safety tipSafety tip

• Not a good idea to modify classes with instantiated objects

• Though it will work• (Just doesn’t work too well right

now)

Class tipsClass tips

• Easiest to put classes into their own file

• Handle all the class setup in the file’s @INIT-tagged function

• One class per file, with all methods in it, works pretty well

Attribute accessAttribute access

• classoffset gets the offset of the first attribute of a class in an object$I5 = classoffset object, ‘Foo’

• getattribute fetches an attribute from an object$P5 = getattribute object, $I5

• You do the math• No protection at this level

MethodsMethods

• Very simple• Optionally add method to .sub

definition• Just names in the class namespace• Classes can override this if they want• Do a leftmost depth-first search for

methods• All __init methods always called when

instantiating

Method callsMethod calls

• Like sub calls, only with an object(foo, bar) = $P6.methname(1,2, ‘3’)

• Nice and simple• Works for all objects (and non-

objects, if they want)

Vtable methodsVtable methods

• Object can override all the PMC vtable functions

• Search up the hierarchy until one is found

• 134 basic vtable methods, so we’re not listing them all here

• Look in vtable.tbl for the list and parameters

• Prepend a __ for the parrot method name

Common vtable methodsCommon vtable methods

__get_integer__get_number__get_string__get_bool__get_pmc

__set_integer_native__set_number_native__set_string_native__assign_string_native__set_bool__set_pmc

MMDMMD

• Only in for some opcode functions right now

• Dispatch based on left and right types

• Basic fallbacks provided• All basic math, comparison, and

bitwise operations covered

MMDMMD

• Use mmdvtregister to add a new function to a tablemmdvtregister MMD_ADD, $I4, $I5, subPMC

• Second and third parameter are type numbers

• Function numbers in runtime/parrot/include/mmd.pasm

• Tables can be dynamically extended

Loading filesLoading files

load_bytecode “file”• Uses same rules as command-line

invocation• PIR and PASM files can be loaded• @LOAD subs of loaded files

executed• Throws exception on error

Debugging supportDebugging support

• -t switch traces all ops• -p switch profiles code• -G or --no-gc disables garbage

collector• --gc-debug enables stressful

collector

Loading external librariesLoading external libraries

• Open the library with loadlib$P4 = loadlib ‘libcurses’

• Create wrappers with dlfunc$P5 = dlfunc $P4, ‘resizeterm’, ‘iii’

• Stick the results somwherestore_global [‘ncurses’], ‘resizeterm’,

$P5

Parameter descriptionsParameter descriptions

I register • c - char• s - short• i - int• l - longN register• f - float• d - doubleS registers stuff• t - character stringP registers • p - data pointer from PMC • P - pointer to a PMC-register• O - pointer to object

Others• 2 - pointer to short• 3 - pointer to int• 4 - pointer to longspecial stuff• 0 - insert a NULL

(pointer)• I - Parrot_Interp• L - Long array• T - Array of string

pointers (Converted to cstrings)

Wrapper subs autogeneratedWrapper subs autogenerated

• In nci.c for the curious• Either dynamically generated by

the JIT, or from a library of stubs• src/call_list.txt has stub list• Format is return value followed by

parameters