1 /* Digital Mars DMDScript source code.
2  * Copyright (c) 2000-2002 by Chromium Communications
3  * D version Copyright (c) 2004-2010 by Digital Mars
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  * written by Walter Bright
7  * http://www.digitalmars.com
8  *
9  * D2 port by Dmitry Olshansky 
10  *
11  * DMDScript is implemented in the D Programming Language,
12  * http://www.digitalmars.com/d/
13  *
14  * For a C++ implementation of DMDScript, including COM support, see
15  * http://www.digitalmars.com/dscript/cppscript.html
16  */
17 
18 
19 module dmdscript.darguments;
20 
21 import dmdscript.script;
22 import dmdscript.dobject;
23 import dmdscript.identifier;
24 import dmdscript.value;
25 import dmdscript.text;
26 import dmdscript.property;
27 
28 // The purpose of Darguments is to implement "value sharing"
29 // per ECMA 10.1.8 between the activation object and the
30 // arguments object.
31 // We implement it by forwarding the property calls from the
32 // arguments object to the activation object.
33 
34 class Darguments : Dobject
35 {
36     Dobject actobj;             // activation object
37     Identifier*[] parameters;
38 
39     override int isDarguments() const
40     {
41         return true;
42     }
43 
44     this(CallContext* cc, Dobject caller, Dobject callee, Dobject actobj,
45          Identifier *[] parameters, Value[] arglist)
46 
47     {
48         super(cc, Dobject.getPrototype(cc));
49 
50         this.actobj = actobj;
51         this.parameters = parameters;
52 
53         if(caller)
54             Put(cc, TEXT_caller, caller, DontEnum);
55         else
56             Put(cc, TEXT_caller, &vnull, DontEnum);
57 
58         Put(cc, TEXT_callee, callee, DontEnum);
59         Put(cc, TEXT_length, arglist.length, DontEnum);
60 
61         for(uint a = 0; a < arglist.length; a++)
62         {
63             Put(cc, a, &arglist[a], DontEnum);
64         }
65     }
66 
67     override Value* Get(d_string PropertyName)
68     {
69         d_uint32 index;
70 
71         return (StringToIndex(PropertyName, index) && index < parameters.length)
72                ? actobj.Get(index)
73                : Dobject.Get(PropertyName);
74     }
75 
76     override Value* Get(d_uint32 index)
77     {
78         return (index < parameters.length)
79                ? actobj.Get(index)
80                : Dobject.Get(index);
81     }
82 
83     override Value* Get(d_uint32 index, Value* vindex)
84     {
85         return (index < parameters.length)
86                ? actobj.Get(index, vindex)
87                : Dobject.Get(index, vindex);
88     }
89 
90     override Value* Put(CallContext* cc, string PropertyName, Value* value, uint attributes)
91     {
92         d_uint32 index;
93 
94         if(StringToIndex(PropertyName, index) && index < parameters.length)
95             return actobj.Put(cc, PropertyName, value, attributes);
96         else
97             return Dobject.Put(cc, PropertyName, value, attributes);
98     }
99 
100     override Value* Put(CallContext* cc, Identifier* key, Value* value, uint attributes)
101     {
102         d_uint32 index;
103 
104         if(StringToIndex(key.value..string, index) && index < parameters.length)
105             return actobj.Put(cc, key, value, attributes);
106         else
107             return Dobject.Put(cc, key, value, attributes);
108     }
109 
110     override Value* Put(CallContext* cc, string PropertyName, Dobject o, uint attributes)
111     {
112         d_uint32 index;
113 
114         if(StringToIndex(PropertyName, index) && index < parameters.length)
115             return actobj.Put(cc, PropertyName, o, attributes);
116         else
117             return Dobject.Put(cc, PropertyName, o, attributes);
118     }
119 
120     override Value* Put(CallContext* cc, string PropertyName, d_number n, uint attributes)
121     {
122         d_uint32 index;
123 
124         if(StringToIndex(PropertyName, index) && index < parameters.length)
125             return actobj.Put(cc, PropertyName, n, attributes);
126         else
127             return Dobject.Put(cc, PropertyName, n, attributes);
128     }
129 
130     override Value* Put(CallContext* cc, d_uint32 index, Value* vindex, Value* value, uint attributes)
131     {
132         if(index < parameters.length)
133             return actobj.Put(cc, index, vindex, value, attributes);
134         else
135             return Dobject.Put(cc, index, vindex, value, attributes);
136     }
137 
138     override Value* Put(CallContext* cc, d_uint32 index, Value* value, uint attributes)
139     {
140         if(index < parameters.length)
141             return actobj.Put(cc, index, value, attributes);
142         else
143             return Dobject.Put(cc, index, value, attributes);
144     }
145 
146     override int CanPut(d_string PropertyName)
147     {
148         d_uint32 index;
149 
150         return (StringToIndex(PropertyName, index) && index < parameters.length)
151                ? actobj.CanPut(PropertyName)
152                : Dobject.CanPut(PropertyName);
153     }
154 
155     override int HasProperty(d_string PropertyName)
156     {
157         d_uint32 index;
158 
159         return (StringToIndex(PropertyName, index) && index < parameters.length)
160                ? actobj.HasProperty(PropertyName)
161                : Dobject.HasProperty(PropertyName);
162     }
163 
164     override int Delete(d_string PropertyName)
165     {
166         d_uint32 index;
167 
168         return (StringToIndex(PropertyName, index) && index < parameters.length)
169                ? actobj.Delete(PropertyName)
170                : Dobject.Delete(PropertyName);
171     }
172 }
173