]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/IteratorOperations.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / IteratorOperations.cpp
CommitLineData
ed1e77d3
A
1/*
2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
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 "IteratorOperations.h"
28
29#include "Error.h"
30#include "JSCInlines.h"
31#include "ObjectConstructor.h"
32
33using namespace WTF;
34
35namespace JSC {
36
37JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value)
38{
39 JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->next);
40 if (exec->hadException())
41 return jsUndefined();
42
43 CallData nextFunctionCallData;
44 CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
45 if (nextFunctionCallType == CallTypeNone)
46 return throwTypeError(exec);
47
48 MarkedArgumentBuffer nextFunctionArguments;
49 if (!value.isEmpty())
50 nextFunctionArguments.append(value);
51 JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments);
52 if (exec->hadException())
53 return jsUndefined();
54
55 if (!result.isObject())
56 return throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object."));
57
58 return result;
59}
60
61JSValue iteratorNext(ExecState* exec, JSValue iterator)
62{
63 return iteratorNext(exec, iterator, JSValue());
64}
65
66JSValue iteratorValue(ExecState* exec, JSValue iterResult)
67{
68 return iterResult.get(exec, exec->vm().propertyNames->value);
69}
70
71bool iteratorComplete(ExecState* exec, JSValue iterResult)
72{
73 JSValue done = iterResult.get(exec, exec->vm().propertyNames->done);
74 return done.toBoolean(exec);
75}
76
77JSValue iteratorStep(ExecState* exec, JSValue iterator)
78{
79 JSValue result = iteratorNext(exec, iterator);
80 if (exec->hadException())
81 return jsUndefined();
82 bool done = iteratorComplete(exec, result);
83 if (exec->hadException())
84 return jsUndefined();
85 if (done)
86 return jsBoolean(false);
87 return result;
88}
89
90void iteratorClose(ExecState* exec, JSValue iterator)
91{
92 Exception* exception = nullptr;
93 if (exec->hadException()) {
94 exception = exec->exception();
95 exec->clearException();
96 }
97 JSValue returnFunction = iterator.get(exec, exec->vm().propertyNames->returnKeyword);
98 if (exec->hadException())
99 return;
100
101 if (returnFunction.isUndefined()) {
102 if (exception)
103 exec->vm().throwException(exec, exception);
104 return;
105 }
106
107 CallData returnFunctionCallData;
108 CallType returnFunctionCallType = getCallData(returnFunction, returnFunctionCallData);
109 if (returnFunctionCallType == CallTypeNone) {
110 if (exception)
111 exec->vm().throwException(exec, exception);
112 else
113 throwTypeError(exec);
114 return;
115 }
116
117 MarkedArgumentBuffer returnFunctionArguments;
118 JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterator, returnFunctionArguments);
119
120 if (exception) {
121 exec->vm().throwException(exec, exception);
122 return;
123 }
124
125 if (exec->hadException())
126 return;
127
128 if (!innerResult.isObject()) {
129 throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object."));
130 return;
131 }
132}
133
134JSObject* createIteratorResultObject(ExecState* exec, JSValue value, bool done)
135{
136 JSObject* resultObject = constructEmptyObject(exec);
137 resultObject->putDirect(exec->vm(), exec->propertyNames().done, jsBoolean(done));
138 resultObject->putDirect(exec->vm(), exec->propertyNames().value, value);
139 return resultObject;
140}
141
142} // namespace JSC