Supported enregistered string and int keys in the vector translator
[hiphop-php.git] / src / runtime / vm / member_operations.cpp
blob35c05e52720f2e9e9d3278e743e9399e05a262d4
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "runtime/vm/member_operations.h"
18 #include "runtime/ext/ext_collection.h"
20 namespace HPHP {
21 namespace VM {
23 StringData* prepareAnyKey(TypedValue* tv) {
24 if (IS_STRING_TYPE(tv->m_type)) {
25 StringData* str = tv->m_data.pstr;
26 str->incRefCount();
27 return str;
28 } else {
29 return tvAsCVarRef(tv).toString().detach();
33 void objArrayAccess(Instance* base) {
34 ASSERT(!base->isCollection());
35 if (!instanceOf(base, "ArrayAccess")) {
36 raise_error("Object does not implement ArrayAccess");
40 TypedValue* objOffsetGet(TypedValue& tvRef, Instance* base,
41 CVarRef offset, bool validate /* = true */) {
42 if (validate) {
43 objArrayAccess(base);
45 TypedValue* result;
46 ASSERT(!base->isCollection());
47 static StringData* sd__offsetGet = StringData::GetStaticString("offsetGet");
48 const Func* method = base->methodNamed(sd__offsetGet);
49 ASSERT(method != NULL);
50 base->invokeUserMethod(&tvRef, method, CREATE_VECTOR1(offset));
51 result = &tvRef;
52 return result;
55 static bool objOffsetExists(Instance* base, CVarRef offset) {
56 objArrayAccess(base);
57 TypedValue tvResult;
58 tvWriteUninit(&tvResult);
59 static StringData* sd__offsetExists
60 = StringData::GetStaticString("offsetExists");
61 ASSERT(!base->isCollection());
62 const Func* method = base->methodNamed(sd__offsetExists);
63 ASSERT(method != NULL);
64 base->invokeUserMethod(&tvResult, method, CREATE_VECTOR1(offset));
65 tvCastToBooleanInPlace(&tvResult);
66 return bool(tvResult.m_data.num);
69 bool objOffsetIsset(TypedValue& tvRef, Instance* base, CVarRef offset,
70 bool validate /* = true */) {
71 return objOffsetExists(base, offset);
74 bool objOffsetEmpty(TypedValue& tvRef, Instance* base, CVarRef offset,
75 bool validate /* = true */) {
76 if (!objOffsetExists(base, offset)) {
77 return true;
79 TypedValue* result = objOffsetGet(tvRef, base, offset, false);
80 ASSERT(result);
81 return empty(tvAsCVarRef(result));
84 void objOffsetAppend(Instance* base, TypedValue* val,
85 bool validate /* = true */) {
86 ASSERT(!base->isCollection());
87 if (validate) {
88 objArrayAccess(base);
90 objOffsetSet(base, init_null_variant, val, false);
93 void objOffsetSet(Instance* base, CVarRef offset, TypedValue* val,
94 bool validate /* = true */) {
95 if (validate) {
96 objArrayAccess(base);
98 static StringData* sd__offsetSet = StringData::GetStaticString("offsetSet");
99 ASSERT(!base->isCollection());
100 const Func* method = base->methodNamed(sd__offsetSet);
101 ASSERT(method != NULL);
102 TypedValue tvResult;
103 tvWriteUninit(&tvResult);
104 base->invokeUserMethod(&tvResult, method,
105 CREATE_VECTOR2(offset, tvAsCVarRef(val)));
106 tvRefcountedDecRef(&tvResult);
109 void objOffsetUnset(Instance* base, CVarRef offset) {
110 objArrayAccess(base);
111 static StringData* sd__offsetUnset
112 = StringData::GetStaticString("offsetUnset");
113 ASSERT(!base->isCollection());
114 const Func* method = base->methodNamed(sd__offsetUnset);
115 ASSERT(method != NULL);
116 TypedValue tv;
117 tvWriteUninit(&tv);
118 base->invokeUserMethod(&tv, method, CREATE_VECTOR1(offset));
119 tvRefcountedDecRef(&tv);
122 ///////////////////////////////////////////////////////////////////////////////