543492f386ab3644aca18daad4f93fd950bbcf9c
[WebKit-https.git] / JavaScriptCore / bindings / runtime_object.cpp
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "error_object.h"
27 #include "function.h"
28 #include "interpreter.h"
29 #include "object.h"
30 #include "operations.h"
31 #include "runtime_method.h"
32 #include "runtime_object.h"
33 #include "types.h"
34 #include "value.h"
35
36
37 #include <assert.h>
38
39 using namespace KJS;
40 using namespace Bindings;
41
42 const ClassInfo RuntimeObjectImp::info = {"RuntimeObject", 0, 0, 0};
43
44 RuntimeObjectImp::RuntimeObjectImp(ObjectImp *proto)
45   : ObjectImp(proto)
46 {
47     instance = 0;
48 }
49
50 RuntimeObjectImp::~RuntimeObjectImp()
51 {
52     if (ownsInstance) {
53         delete instance;
54     }
55 }
56
57 RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp ((ObjectImp *)0)
58 {
59     ownsInstance = oi;
60     instance = i;
61 }
62
63 Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) const
64 {
65     Value result = Undefined();
66
67     instance->begin();
68     
69     Class *aClass = instance->getClass();
70     
71     if (aClass) {
72         
73         // See if the instance have a field with the specified name.
74         Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
75         if (aField) {
76             result = instance->getValueOfField (exec, aField); 
77         }
78         else {
79             // Now check if a method with specified name exists, if so return a function object for
80             // that method.
81             MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
82             if (methodList.length() > 0) {
83                 result = Object (new RuntimeMethodImp(exec, propertyName, methodList));
84             }
85         }
86     
87         if (result.type() == UndefinedType) {
88             // Try a fallback object.
89             result = aClass->fallbackObject (exec, instance, propertyName);
90         }
91     }
92         
93         
94     instance->end();
95
96     return result;
97 }
98
99 void RuntimeObjectImp::put(ExecState *exec, const Identifier &propertyName,
100                     const Value &value, int attr)
101 {
102     instance->begin();
103
104     // Set the value of the property.
105     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
106     if (aField) {
107         getInternalInstance()->setValueOfField(exec, aField, value);
108     }
109     else {
110         getInternalInstance()->setValueOfUndefinedField(exec, propertyName, value);
111     }
112
113     instance->end();
114 }
115
116 bool RuntimeObjectImp::canPut(ExecState *exec, const Identifier &propertyName) const
117 {
118     instance->begin();
119
120     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
121
122     instance->end();
123
124     return aField ? true : false;
125 }
126
127 bool RuntimeObjectImp::hasProperty(ExecState *exec,
128                             const Identifier &propertyName) const
129 {
130     instance->begin();
131
132     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
133     if (aField) {
134         instance->end();
135         return true;
136     }
137         
138     MethodList methodList = instance->getClass()->methodsNamed(propertyName.ascii(), instance);
139
140     instance->end();
141
142     if (methodList.length() > 0)
143         return true;
144         
145     return false;
146 }
147
148 bool RuntimeObjectImp::deleteProperty(ExecState *exec,
149                             const Identifier &propertyName)
150 {
151     // Can never remove a property of a RuntimeObject.
152     return false;
153 }
154
155 Value RuntimeObjectImp::defaultValue(ExecState *exec, Type hint) const
156 {
157     instance->begin();
158
159     Value aValue = getInternalInstance()->defaultValue(hint);
160     
161     instance->end();
162     
163     return aValue;
164 }
165     
166 bool RuntimeObjectImp::implementsCall() const
167 {
168     // Only true for default functions.
169     return true;
170 }
171
172 Value RuntimeObjectImp::call(ExecState *exec, Object &thisObj, const List &args)
173 {
174     instance->begin();
175
176     Value aValue = getInternalInstance()->invokeDefaultMethod(exec, args);
177     
178     instance->end();
179     
180     return aValue;
181 }
182