e4f5946c122ce0f02c04f98e2ccea60e09ba287e
[WebKit-https.git] / Source / JavaScriptCore / API / JSBase.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2013 Apple 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 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 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 "config.h"
27 #include "JSBase.h"
28 #include "JSBasePrivate.h"
29
30 #include "APICast.h"
31 #include "CallFrame.h"
32 #include "Completion.h"
33 #include "GCActivityCallback.h"
34 #include "InitializeThreading.h"
35 #include "JSGlobalObject.h"
36 #include "JSLock.h"
37 #include "JSObject.h"
38 #include "OpaqueJSString.h"
39 #include "JSCInlines.h"
40 #include "SourceCode.h"
41 #include <wtf/text/StringHash.h>
42
43 #if ENABLE(REMOTE_INSPECTOR)
44 #include "JSGlobalObjectInspectorController.h"
45 #endif
46
47 using namespace JSC;
48
49 JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
50 {
51     if (!ctx) {
52         ASSERT_NOT_REACHED();
53         return 0;
54     }
55     ExecState* exec = toJS(ctx);
56     JSLockHolder locker(exec);
57
58     JSObject* jsThisObject = toJS(thisObject);
59
60     startingLineNumber = std::max(1, startingLineNumber);
61
62     // evaluate sets "this" to the global object if it is NULL
63     JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
64     SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
65
66     JSValue evaluationException;
67     JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException);
68
69     if (evaluationException) {
70         if (exception)
71             *exception = toRef(exec, evaluationException);
72 #if ENABLE(REMOTE_INSPECTOR)
73         // FIXME: If we have a debugger attached we could learn about ParseError exceptions through
74         // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The
75         // Debugger path is currently ignored by inspector.
76         // NOTE: If we don't have a debugger, this SourceCode will be forever lost to the inspector.
77         // We could stash it in the inspector in case an inspector is ever opened.
78         globalObject->inspectorController().reportAPIException(exec, evaluationException);
79 #endif
80         return 0;
81     }
82
83     if (returnValue)
84         return toRef(exec, returnValue);
85
86     // happens, for example, when the only statement is an empty (';') statement
87     return toRef(exec, jsUndefined());
88 }
89
90 bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
91 {
92     if (!ctx) {
93         ASSERT_NOT_REACHED();
94         return false;
95     }
96     ExecState* exec = toJS(ctx);
97     JSLockHolder locker(exec);
98
99     startingLineNumber = std::max(1, startingLineNumber);
100
101     SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
102     
103     JSValue syntaxException;
104     bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
105
106     if (!isValidSyntax) {
107         if (exception)
108             *exception = toRef(exec, syntaxException);
109 #if ENABLE(REMOTE_INSPECTOR)
110         exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, syntaxException);
111 #endif
112         return false;
113     }
114
115     return true;
116 }
117
118 void JSGarbageCollect(JSContextRef ctx)
119 {
120     // We used to recommend passing NULL as an argument here, which caused the only heap to be collected.
121     // As there is no longer a shared heap, the previously recommended usage became a no-op (but the GC
122     // will happen when the context group is destroyed).
123     // Because the function argument was originally ignored, some clients may pass their released context here,
124     // in which case there is a risk of crashing if another thread performs GC on the same heap in between.
125     if (!ctx)
126         return;
127
128     ExecState* exec = toJS(ctx);
129     JSLockHolder locker(exec);
130
131     exec->vm().heap.reportAbandonedObjectGraph();
132 }
133
134 void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
135 {
136     if (!ctx) {
137         ASSERT_NOT_REACHED();
138         return;
139     }
140     ExecState* exec = toJS(ctx);
141     JSLockHolder locker(exec);
142     exec->vm().heap.reportExtraMemoryCost(size);
143 }
144
145 extern "C" JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);
146 extern "C" JS_EXPORT void JSSynchronousEdenCollectForDebugging(JSContextRef);
147
148 void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx)
149 {
150     if (!ctx)
151         return;
152
153     ExecState* exec = toJS(ctx);
154     JSLockHolder locker(exec);
155     exec->vm().heap.collectAllGarbage();
156 }
157
158 void JSSynchronousEdenCollectForDebugging(JSContextRef ctx)
159 {
160     if (!ctx)
161         return;
162
163     ExecState* exec = toJS(ctx);
164     JSLockHolder locker(exec);
165     exec->vm().heap.collect(EdenCollection);
166 }
167
168 void JSDisableGCTimer(void)
169 {
170     GCActivityCallback::s_shouldCreateGCTimer = false;
171 }
172
173 #if PLATFORM(IOS)
174 // FIXME: Expose symbols to tell dyld where to find JavaScriptCore on older versions of
175 // iOS (< 7.0). We should remove these symbols once we no longer need to support such
176 // versions of iOS. See <rdar://problem/13696872> for more details.
177 JS_EXPORT extern const char iosInstallName43 __asm("$ld$install_name$os4.3$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
178 JS_EXPORT extern const char iosInstallName50 __asm("$ld$install_name$os5.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
179 JS_EXPORT extern const char iosInstallName51 __asm("$ld$install_name$os5.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
180 JS_EXPORT extern const char iosInstallName60 __asm("$ld$install_name$os6.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
181 JS_EXPORT extern const char iosInstallName61 __asm("$ld$install_name$os6.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
182
183 const char iosInstallName43 = 0;
184 const char iosInstallName50 = 0;
185 const char iosInstallName51 = 0;
186 const char iosInstallName60 = 0;
187 const char iosInstallName61 = 0;
188 #endif