Skip to content

Commit 9453e7f

Browse files
committed
[truffle] Implement native types on variables
1 parent 131819e commit 9453e7f

File tree

9 files changed

+353
-24
lines changed

9 files changed

+353
-24
lines changed

src/vm/jvm/Truffle.nqp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,14 @@ class QAST::TruffleCompiler {
417417
has $!qast; # The QAST::Block
418418
has $!outer; # Outer block's BlockInfo
419419
has @!params; # the parameters the block takes
420+
has $!var_types; # Mapping of variables types
421+
422+
method var_type($var) {
423+
$!var_types{$var.scope}{$var.name};
424+
}
425+
method register_var_type($var, $type) {
426+
$!var_types{$var.scope}{$var.name} := $type;
427+
}
420428

421429
method new($qast, $outer) {
422430
my $obj := nqp::create(self);
@@ -428,13 +436,15 @@ class QAST::TruffleCompiler {
428436
$!qast := $qast;
429437
$!outer := $outer;
430438
@!params := nqp::list();
439+
$!var_types := nqp::hash('local', nqp::hash(), 'lexical', nqp::hash());
431440
}
432441

433442
method add_param($param) {
434443
@!params.push($param);
435444
}
436445

437446
method params() { @!params }
447+
method outer() { $!outer }
438448
}
439449

440450
method compile(QAST::CompUnit $cu) {
@@ -547,6 +557,37 @@ class QAST::TruffleCompiler {
547557
}
548558
}
549559

560+
my @types := [$OBJ, $INT, $NUM, $STR];
561+
method type_from_typeobj($typeobj) {
562+
my int $type := nqp::objprimspec($typeobj);
563+
@types[$type];
564+
}
565+
566+
method figure_out_type(QAST::Var $var) {
567+
my $type := $*BLOCK.var_type($var);
568+
if nqp::defined($type) {
569+
return $type;
570+
}
571+
572+
if $var.scope eq 'lexical' || $var.scope eq 'typevar' {
573+
# Try to find it in an outer scope.
574+
my $cur_block := $*BLOCK.outer();
575+
while nqp::istype($cur_block, BlockInfo) {
576+
$type := $cur_block.var_type($var);
577+
if nqp::defined($type) {
578+
return $type;
579+
}
580+
else {
581+
$cur_block := $cur_block.outer();
582+
}
583+
}
584+
}
585+
586+
# TODO var not found and has .returns
587+
588+
$OBJ;
589+
}
590+
550591
proto method as_truffle($node, :$want) {
551592
if nqp::defined($want) {
552593
if nqp::istype($node, QAST::Want) {
@@ -567,6 +608,8 @@ class QAST::TruffleCompiler {
567608
$*HLL := $node.hll;
568609
}
569610

611+
my $*BLOCK := BlockInfo.new(NQPMu, NQPMu);
612+
570613
TAST.new($OBJ, ['stmts', self.as_truffle($node[0][1], :want($VOID)).tree, self.as_truffle($node[0][3], :want($OBJ)).tree]);
571614
}
572615

@@ -688,21 +731,25 @@ class QAST::TruffleCompiler {
688731
multi method as_truffle(QAST::Var $node, :$want) {
689732
my $action;
690733

734+
my $type := self.figure_out_type($node);
735+
691736
if $node.scope eq 'lexical' || $node.scope eq 'local' {
692737
my str $scope := $node.scope;
693738
if $*BINDVAL {
694-
my $value := self.as_truffle_clear_bindval($*BINDVAL, :want($OBJ));
695-
$action := ["bind-$scope", $node.name, $value.tree];
739+
my $value := self.as_truffle_clear_bindval($*BINDVAL, :want($type));
740+
$action := ["bind-{nqp::lc(%type_names{$type})}-$scope", $node.name, $value.tree];
696741
} else {
697742
$action := ["get-$scope", $node.name];
698743
}
699744

700745
if $node.decl eq '' {
701-
return TAST.new($OBJ, $action);
746+
return TAST.new($type, $action);
702747
}
703748
# TODO static should do deserialization
704749
elsif $node.decl eq 'var' || $node.decl eq 'static' {
705-
return TAST.new($OBJ, ["declare-$scope", $node.name, $action]);
750+
my int $type := self.type_from_typeobj($node.returns);
751+
$*BLOCK.register_var_type($node, $type);
752+
return TAST.new($type, ["declare-$scope", $type, $node.name, $action]);
706753
}
707754
elsif $node.decl eq 'param' {
708755
$*BLOCK.add_param($node);

src/vm/jvm/runtime/org/perl6/nqp/truffle/ManageScopes.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
import com.oracle.truffle.api.frame.FrameDescriptor;
44
import com.oracle.truffle.api.frame.FrameSlot;
5+
import com.oracle.truffle.api.frame.FrameSlotKind;
56

67
import org.perl6.nqp.truffle.nodes.NQPNode;
78
import org.perl6.nqp.truffle.nodes.NQPBlockBodyNode;
89
import org.perl6.nqp.truffle.nodes.control.NQPBlockNode;
910

11+
import org.perl6.nqp.truffle.MalformedAstException;
12+
13+
1014
import org.perl6.nqp.dsl.Predeserializer;
1115
import org.perl6.nqp.dsl.Deserializer;
1216

@@ -25,25 +29,36 @@ public static NQPNode createBlock(NQPScope scope, NQPNode[] children) {
2529
);
2630
}
2731

32+
private static FrameSlotKind kindFromType(long type) {
33+
switch ((int)type) {
34+
case 0: return FrameSlotKind.Object;
35+
case 1: return FrameSlotKind.Long;
36+
case 2: return FrameSlotKind.Double;
37+
case 3: return FrameSlotKind.Object;
38+
default: throw new MalformedAstException("Wrong variable type: " + type);
39+
}
40+
}
41+
42+
2843
@Predeserializer("declare-lexical")
29-
public static NQPScope declareLexical(NQPScope scope, String name) {
44+
public static NQPScope declareLexical(NQPScope scope, long type, String name) {
3045
scope.addLexical(name);
3146
return scope;
3247
}
3348

3449
@Deserializer("declare-lexical")
35-
public static NQPNode createDeclareLexical(NQPScope scope, String name, NQPNode inner) {
50+
public static NQPNode createDeclareLexical(NQPScope scope, long type, String name, NQPNode inner) {
3651
return inner;
3752
}
3853

3954
@Predeserializer("declare-local")
40-
public static NQPScope declareLocal(NQPScope scope, String name) {
55+
public static NQPScope declareLocal(NQPScope scope, long type, String name) {
4156
scope.addLocal(name);
4257
return scope;
4358
}
4459

4560
@Deserializer("declare-local")
46-
public static NQPNode createDeclareLocal(NQPScope scope, String name, NQPNode inner) {
61+
public static NQPNode createDeclareLocal(NQPScope scope, long type, String name, NQPNode inner) {
4762
return inner;
4863
}
4964
}

src/vm/jvm/runtime/org/perl6/nqp/truffle/nodes/NQPWhileNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public WhileRepeatingNode(NQPNode condNode, NQPNode bodyNode) {
4444
public boolean executeRepeating(VirtualFrame frame) {
4545
if (toBoolean(condNode.execute(frame))) {
4646
try {
47-
bodyNode.execute(frame);
47+
bodyNode.executeVoid(frame);
4848
} catch (ContinueException ex) {
4949
// the body might throw a continue control-flow exception
5050
// continue loop invocation
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.perl6.nqp.truffle.nodes.variables;
42+
43+
import com.oracle.truffle.api.frame.FrameSlot;
44+
import com.oracle.truffle.api.frame.VirtualFrame;
45+
import org.perl6.nqp.truffle.nodes.NQPNode;
46+
47+
import org.perl6.nqp.dsl.Deserializer;
48+
49+
import org.perl6.nqp.truffle.NQPScope;
50+
import org.perl6.nqp.truffle.FoundLexical;
51+
52+
public class NQPBindIntVariableNode extends FrameLookupNode {
53+
final private FrameSlot slot;
54+
@Child private NQPNode valueNode;
55+
56+
public NQPBindIntVariableNode(FrameSlot slot, int depth, NQPNode valueNode) {
57+
super(depth);
58+
this.slot = slot;
59+
this.valueNode = valueNode;
60+
}
61+
62+
@Override
63+
public long executeInt(VirtualFrame frame) {
64+
long value = valueNode.executeInt(frame);
65+
getFrame(frame).setLong(slot, value);
66+
return value;
67+
}
68+
69+
@Deserializer("bind-int-lexical")
70+
public static NQPBindIntVariableNode bindLexical(NQPScope scope, String name, NQPNode valueNode) {
71+
FoundLexical foundLexical = scope.findLexical(name);
72+
return new NQPBindIntVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth(), valueNode);
73+
}
74+
75+
@Deserializer("bind-int-local")
76+
public static NQPBindIntVariableNode bindLocal(NQPScope scope, String name, NQPNode valueNode) {
77+
return new NQPBindIntVariableNode(scope.findLocal(name), 0, valueNode);
78+
}
79+
80+
@Override
81+
public void executeVoid(VirtualFrame frame) {
82+
executeInt(frame);
83+
}
84+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.perl6.nqp.truffle.nodes.variables;
42+
43+
import com.oracle.truffle.api.frame.FrameSlot;
44+
import com.oracle.truffle.api.frame.VirtualFrame;
45+
import org.perl6.nqp.truffle.nodes.NQPNode;
46+
47+
import org.perl6.nqp.dsl.Deserializer;
48+
49+
import org.perl6.nqp.truffle.NQPScope;
50+
import org.perl6.nqp.truffle.FoundLexical;
51+
52+
public class NQPBindNumVariableNode extends FrameLookupNode {
53+
final private FrameSlot slot;
54+
@Child private NQPNode valueNode;
55+
56+
public NQPBindNumVariableNode(FrameSlot slot, int depth, NQPNode valueNode) {
57+
super(depth);
58+
this.slot = slot;
59+
this.valueNode = valueNode;
60+
}
61+
62+
@Override
63+
public double executeNum(VirtualFrame frame) {
64+
double value = valueNode.executeNum(frame);
65+
getFrame(frame).setDouble(slot, value);
66+
return value;
67+
}
68+
69+
@Deserializer("bind-num-lexical")
70+
public static NQPBindNumVariableNode bindLexical(NQPScope scope, String name, NQPNode valueNode) {
71+
FoundLexical foundLexical = scope.findLexical(name);
72+
return new NQPBindNumVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth(), valueNode);
73+
}
74+
75+
@Deserializer("bind-num-local")
76+
public static NQPBindNumVariableNode bindLocal(NQPScope scope, String name, NQPNode valueNode) {
77+
return new NQPBindNumVariableNode(scope.findLocal(name), 0, valueNode);
78+
}
79+
80+
@Override
81+
public void executeVoid(VirtualFrame frame) {
82+
executeNum(frame);
83+
}
84+
}

0 commit comments

Comments
 (0)